如何在Android中使用拖放功能交换两个图像视图? [英] How to swap two image views using drag and drop in Android?

查看:199
本文介绍了如何在Android中使用拖放功能交换两个图像视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试在Android中实现一个非常简单的拖放操作,拖放的项目将与放置的项目交换位置。



ve成功实现了onLongClick和onDrag侦听器。当我拖放一个项目时,它会替换被删除的项目,但是我无法确定替换的项目是否取代了拖动的项目。



我花了一段时间寻找答案,但大多数答案只是链接复杂的拖放实现,涉及许多文件,包含大量代码,我无法理解它们将其应用于我的代码。



我原来假设我没有获得ImageView的真实副本,

  ImageView temp =(ImageView)event.getLocalState(); 

所以我试过

 ImageView dragged =(ImageView)findViewById(temp.getId()); 

但没有什么不同。



我几乎可以肯定的问题是在'OnDragListener',在'case DragEvent.ACTION_DROP:'。
这是我的代码(从Main.java):

  public class Main extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

findViewById(R.id.ball1).setOnLongClickListener(listenClick);
findViewById(R.id.ball1).setOnDragListener(listenDrag);
findViewById(R.id.target1).setOnLongClickListener(listenClick);
findViewById(R.id.target1).setOnDragListener(listenDrag);
findViewById(R.id.target2).setOnDragListener(listenDrag);
findViewById(R.id.target2).setOnLongClickListener(listenClick);
findViewById(R.id.target3).setOnDragListener(listenDrag);
findViewById(R.id.target3).setOnLongClickListener(listenClick);



View.OnLongClickListener listenClick = new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View v)
{

ClipData data = ClipData.newPlainText(,);
DragShadow dragShadow = new DragShadow(v);

v.startDrag(data,dragShadow,v,0);

返回false;
}
};

private class DragShadow extends View.DragShadowBuilder
{
ColorDrawable greyBox;

public DragShadow(查看视图)
{
super(view);
greyBox = new ColorDrawable(Color.LTGRAY);
}

@Override
public void onDrawShadow(Canvas canvas)
{
greyBox.draw(canvas);


@Override
public void onProvideShadowMetrics(Point shadowSize,
Point shadowTouchPoint)
{
查看v = getView();

int height =(int)v.getHeight();
int width =(int)v.getWidth();

greyBox.setBounds(0,0,width,height);

shadowSize.set(width,height);

shadowTouchPoint.set((int)width / 2,(int)height / 2);
}
}



View.OnDragListener listenDrag = new View.OnDragListener(){

@Override
public boolean onDrag(View v,DragEvent event)
{
int dragEvent = event.getAction();

switch(dragEvent)
{
case DragEvent.ACTION_DRAG_ENTERED:
Log.i(Drag Event,Entered);
break;

case DragEvent.ACTION_DRAG_EXITED:
Log.i(Drag Event,Exited);
break;

case DragEvent.ACTION_DROP:
ImageView target =(ImageView)v;

ImageView temp =(ImageView)event.getLocalState();
ImageView dragged =(ImageView)findViewById(temp.getId());


target.setId(dragged.getId());
target.setImageDrawable(dragged.getDrawable());

dragged.setId(temp.getId());
dragged.setImageDrawable(temp.getDrawable());

break;

}

return true;
}
};

如果有人可以告诉我为什么setImageDrawable在目标上工作,但不是拖动,我会非常感激。

解决方案

计算机科学的一个伟大的乐趣是学习谦卑。至少90%的时间,对追求的答案:为什么这不工作?是你告诉电脑做错了的事情。



在case DragEvent.ACTION_DROP:我正在获得这两个视图的引用。因为某些原因我没有意识到,当我做了

  target.setImageDrawable(dragged.getDrawable()); 

我也改变了temp的可绘制,因为temp是指实际的视图。因为这样,当我做了

  dragged.setImageDrawable(temp.getDrawable()); 

我其实只是将拖动的可绘制设置为原来的。
这是更正的代码。

  case DragEvent.ACTION_DROP:
ImageView target =(ImageView)v ;

ImageView dragged =(ImageView)event.getLocalState();

Drawable target_draw = target.getDrawable();
Drawable dragged_draw = dragged.getDrawable();

dragged.setImageDrawable(target_draw);
target.setImageDrawable(dragged_draw);

break;


I've been trying to implement a very simple drag and drop in Android, where the dragged item swaps positions with the item it was dropped on.

I've successfully implemented the onLongClick and onDrag listeners. When I drag and drop an item it replaces the item it was dropped on, but I can't figure out how make the replaced item take the place of the dragged item.

I spent a while searching for answers, but most answers just linked complex implementations of drag and drop involving many files with lots of code, and I wasn't able to understand them enough to apply them to my code.

I originally assumed that I wasn't getting a true copy of the ImageView with

ImageView temp = (ImageView) event.getLocalState();

so I tried

ImageView dragged = (ImageView) findViewById(temp.getId());  

but that didn't make a difference.

I'm almost certain the problem is in the 'OnDragListener', in the 'case DragEvent.ACTION_DROP:'. Here is my code (from Main.java):

public class Main extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.ball1).setOnLongClickListener(listenClick);
        findViewById(R.id.ball1).setOnDragListener(listenDrag);
        findViewById(R.id.target1).setOnLongClickListener(listenClick);
        findViewById(R.id.target1).setOnDragListener(listenDrag);
        findViewById(R.id.target2).setOnDragListener(listenDrag);
        findViewById(R.id.target2).setOnLongClickListener(listenClick);
        findViewById(R.id.target3).setOnDragListener(listenDrag);
        findViewById(R.id.target3).setOnLongClickListener(listenClick);



View.OnLongClickListener listenClick = new View.OnLongClickListener()
    {
        @Override
        public boolean onLongClick(View v)
        {

            ClipData data = ClipData.newPlainText("","");
            DragShadow dragShadow = new DragShadow(v);

            v.startDrag(data, dragShadow, v, 0);

            return false;
        }
    };

    private class DragShadow extends View.DragShadowBuilder
    {
        ColorDrawable greyBox;

        public DragShadow(View view)
        {
            super(view);
            greyBox = new ColorDrawable(Color.LTGRAY);
        }

        @Override
        public void onDrawShadow(Canvas canvas)
        {
            greyBox.draw(canvas);
        }

        @Override
        public void onProvideShadowMetrics(Point shadowSize,
                                           Point shadowTouchPoint)
        {
            View v = getView();

            int height = (int) v.getHeight();
            int width = (int) v.getWidth();

            greyBox.setBounds(0, 0, width, height);

            shadowSize.set(width, height);

            shadowTouchPoint.set((int)width/2, (int)height/2);
        }
    }



View.OnDragListener listenDrag = new View.OnDragListener() {

        @Override
        public boolean onDrag(View v, DragEvent event)
        {
            int dragEvent = event.getAction();

            switch (dragEvent)
            {
                case DragEvent.ACTION_DRAG_ENTERED:
                    Log.i("Drag Event", "Entered");
                    break;

                case DragEvent.ACTION_DRAG_EXITED:
                    Log.i("Drag Event", "Exited");
                    break;

                case DragEvent.ACTION_DROP:
                    ImageView target = (ImageView) v;

                    ImageView temp = (ImageView) event.getLocalState();
                    ImageView dragged = (ImageView) findViewById(temp.getId());


                    target.setId(dragged.getId());
                    target.setImageDrawable(dragged.getDrawable());

                    dragged.setId(temp.getId());
                    dragged.setImageDrawable(temp.getDrawable());

                    break;

            }

            return true;
        }
    };

If anyone can tell me why the setImageDrawable works on target, but not on dragged, I'll be very grateful.

解决方案

One of the great joys of being in Computer Science is learning humility. At least 90% of the time, the answer to the quest: "Why isn't this working?" is that you told the computer to do the wrong thing.

In "case DragEvent.ACTION_DROP:" I was getting references to both views. What I wasn't realizing for some reason is that when I did

target.setImageDrawable(dragged.getDrawable());

I was also changing the drawable of temp, since temp was referring to the actual view. Because of that when I did

dragged.setImageDrawable(temp.getDrawable());

I was actually just setting dragged's drawable to what it originally was. Here is the corrected code.

            case DragEvent.ACTION_DROP:
                ImageView target = (ImageView) v;

                ImageView dragged = (ImageView) event.getLocalState();

                Drawable target_draw = target.getDrawable();
                Drawable dragged_draw = dragged.getDrawable();

                dragged.setImageDrawable(target_draw);
                target.setImageDrawable(dragged_draw);

                break;

这篇关于如何在Android中使用拖放功能交换两个图像视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆