drag and drop学习

原创 2015年11月21日 09:47:12

首先由文档中介绍所说,drag and drop手势是用于将一个View中的数据放到另一个View中,同时还可以用于UI相关的动作

其次其应用的步骤为:首先新建一个类实现View.OnDragListener,该类用于drag and drop事件发生时的回调,然后再新建一个类继承自View.DragShadowBuilder用于设置动作发生时随拖动而移动的阴影图像,最后设置监听,然后在当你认为该动作是为了触发drag and drop时调用View的startDrag方法即可。

值得注意的就是当用户手指在当前的布局上拖拽阴影时,系统会向当前的注册了dragListener的View发送drag event,这里的View是当前布局上所有的View,假设你有6个View都注册了dragListener,那么当其中一个View调用startDrag方法时,其他的View的drag_start事件同样发生。

下面是一个小例子,在5个ImageView均可拖动,当拖动一个到另一个ImageView上drop时,则交换二个ImageView的src图片

public class MainActivity extends Activity {

    private ImageView imageView[];
    private TextView textView;
    private int []imageId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        textView.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                return true;
            }
        });
        imageView = new ImageView[5];
        imageId=new int[5];
        myDragEventListener dragEventListener = new myDragEventListener();
        for (int i = 0; i < 5; i++) {
            int id = getResources().getIdentifier("image_view0" + (i + 1), "id", getPackageName());
            imageView[i] = (ImageView) findViewById(id);
            imageView[i].setOnDragListener(dragEventListener);
            imageView[i].setTag(i);
            final int finalI = i;
            final int bid = getResources().getIdentifier("a" + (i + 1), "drawable", getPackageName());
            imageId[i]=bid;
            imageView[i].setOnLongClickListener(new View.OnLongClickListener() {
                public boolean onLongClick(View v) {
                    View.DragShadowBuilder myShadow = new MyDragShadowBuilder(imageView[finalI], getResources(), imageId[finalI]);
                    v.startDrag(null, myShadow, null, 0);
                    return true;
                }
            });
        }
    }

    /**
     * 该类用于构造显示拖拽的阴影
     */
    private static class MyDragShadowBuilder extends View.DragShadowBuilder {
        private static Drawable shadow;
        /**
         * 构造阴影
         * @param v
         * @param res
         * @param id
         */
        public MyDragShadowBuilder(View v, Resources res, int id) {
            super(v);
            shadow = new BitmapDrawable(BitmapFactory.decodeResource(res,id));
            shadow.setAlpha(126);
        }

        /**
         * 设定阴影的大小、手指位于阴影的位置
         * @param size
         * @param touch
         */
        @Override
        public void onProvideShadowMetrics(Point size, Point touch) {
            int width, height;
            width = getView().getWidth();
            height = getView().getHeight();
            shadow.setBounds(0, 0, width, height);
            size.set(width, height);
            touch.set(width / 2, height / 2);
        }

        /**
         * 将阴影绘制到canvas上以以供显示
         * @param canvas
         */
        @Override
        public void onDrawShadow(Canvas canvas) {
            shadow.draw(canvas);
        }
    }

    /**
     * 拖拽事件的回调
     */
    protected class myDragEventListener implements View.OnDragListener {
        private ImageView image;
        private boolean flag;
        public boolean onDrag(View v, DragEvent event) {
            final int action = event.getAction();
            switch (action) {
                //当拖拽手势开始时调用,当前布局上所有注册了dragListener的View的相应事件都发生回调
                case DragEvent.ACTION_DRAG_STARTED:
                    flag=true;
                    return true;
                //当拖拽的阴影进入View时回调
                case DragEvent.ACTION_DRAG_ENTERED:
                    if(flag){//第一个为要拖拽的View,将至隐藏
                        flag=false;
                        image= (ImageView) v;
                        image.setVisibility(View.INVISIBLE);
                    }
                    else {
                        ((ImageView) v).setColorFilter(Color.parseColor("#cccccccc"), PorterDuff.Mode.LIGHTEN);
                    }
                    v.invalidate();
                    return true;
                //拖拽的阴影位于当前View时回调
                case DragEvent.ACTION_DRAG_LOCATION:
                    return true;
                //拖拽的阴影离开View时回调
                case DragEvent.ACTION_DRAG_EXITED:
                    ((ImageView) v).clearColorFilter();
                    v.invalidate();
                    return true;
                //拖拽的阴影放入数据到View时回调
                case DragEvent.ACTION_DROP:
                    ((ImageView)v).clearColorFilter();
                    Drawable d=((ImageView)v).getDrawable();
                    ((ImageView)v).setImageDrawable(image.getDrawable());
                    image.setImageDrawable(d);
                    image.setVisibility(View.VISIBLE);
                    int index1= (int) v.getTag();
                    int index2= (int) image.getTag();
                    int tmp=imageId[index2];
                    imageId[index2]=imageId[index1];
                    imageId[index1]=tmp;
                    v.invalidate();
                    return true;
                //托拽事件结束时所有View的事件回调
                case DragEvent.ACTION_DRAG_ENDED:
                    ((ImageView) v).clearColorFilter();
                    if (event.getResult()) {//如果该拖拽存在数据且DROP事件被处理了,则返回值为真
                        Toast.makeText(MainActivity.this, "The drop was handled.", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, "The drop didn't work.", Toast.LENGTH_LONG).show();
                    }
                    v.invalidate();
                    return true;
            }
            return false;
        }
    }
}
布局文件很简单,就是一个LinearLayout中垂直放置了5个ImageView和一个TextView

Drop and Drag API学习与整理

原文链接: Drop和Drag是能够DOM元素拖动与释放的API。过去我们也有一个能够实现拖动与释放的流程。今天总结一下,可以看到新的API是给我们提供了很大的便利和简化了许多代码的。拖拽的旧方法总...
  • Christine95
  • Christine95
  • 2016年03月06日 22:37
  • 1173

SVGElement Drag & Drop

var dx, dy; var x, y; var actived = null; function mouseDownListener(e){ if(actived.setCapture...
  • wildwind79
  • wildwind79
  • 2016年06月18日 01:08
  • 145

Drag &amp; Drop 全解析

 一、基本概念拖放,是指用鼠标拖动的方法,在不同程序的窗口之间、同一个程序的不同窗口之间或同一程序同一窗口的不同控件之间,进行移动、复制和粘贴等操作的技术。拖放操作是在操作系统的帮助下完成的。被拖动的...
  • yangdelong
  • yangdelong
  • 2007年08月07日 15:03
  • 3388

Windows中Drag&Drop初探(一)

一、基本概念     拖放,是指用鼠标拖动的方法,在不同程序的窗口之间、同一个程序的不同窗口之间或同一程序同一窗口的不同控件之间,进行移动、复制和粘贴等操作的技术。拖放操作是在操作系统的帮助下完成的。...
  • codewarrior
  • codewarrior
  • 2004年06月15日 10:56
  • 5815

Android 用户界面---拖放(Drag and Drop)(三)

设计拖放操作 本节主要内容如下: 1.  如何开始拖拽; 2.  在拖拽期间如何响应事件; 3.  如何响应落下事件; 4.  如何结束拖放操作。 开始拖拽 用户使用一个拖拽手势开始拖拽...
  • FireOfStar
  • FireOfStar
  • 2012年03月29日 19:09
  • 15800

HTML5拖放(drag和drop)

1. 说说“拖放事件” 拖放事件,即抓取对象以后拖动到另一个位置 有些事件在被拖放的元素上触发,有些在放置目标上触发。在拖动元素时,依次触发dragstart事件、drag事件、drag...
  • xiaguangzhiying
  • xiaguangzhiying
  • 2016年06月21日 17:11
  • 1625

Android:Drag and Drop的应用

最近看了下Drag and Drop部分的原文,觉得很有意思就像自己试着做一下,说实在的原文真的是不好读啊,要感谢那些为我们发表译文的大神们, 真的是不容易,原文中给了例子,但是只有后面零星的代码,真...
  • zd_1471278687
  • zd_1471278687
  • 2014年03月03日 15:34
  • 6524

.NET中的Drag and Drop操作(二)

在上一篇文章介绍了在.NET中进行Drag和Drop操作的方法,以及底层的调用实现过程。实际是通过一个DoDragDrop的WIN32 API来监视拖拽过程中的鼠标,根据鼠标的位置获得IDropTra...
  • jumtre
  • jumtre
  • 2013年12月11日 11:21
  • 1858

html5篇——拖放(Drag和Drop)

好久没有更新html5了,继续更新html5,今天更新html5的拖放功能。 拖放,就是抓取一个对象后拖放到另一个位置。很常用的一个功能,在html5中,任何元素都能够拖放。 浏览器支持 Inter...
  • u010556394
  • u010556394
  • 2016年05月30日 17:23
  • 1391

.NET中的Drag and Drop操作(三)

前两篇文件介绍了.NET平台下Drag and Drop操作的原理以及整个拖拽的过程,还分析了拖拽过程中的数据的格式。本篇是这个小系列的最后一篇,主要是通过列子介绍.NET程序如何与Windows S...
  • jumtre
  • jumtre
  • 2013年12月11日 13:05
  • 2937
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:drag and drop学习
举报原因:
原因补充:

(最多只允许输入30个字)