如何使用Android的拖拽接口实现拖拽功能

2017-02-10 14:45
582

转载注明出处:JEESNS-十个雨点

简介

拖拽操作在现在的智能手机中并不少见,老罗的OneStep更是把拖拽做成了一种令人拍手叫绝的交互方式。在锤子手机原生的Bigbang中,普通拖动是多选文字,长按选中的文字并拖动是触发OneStep的分享功能。而我在模仿Bigbang的时候,觉得用户可能需要对文字进行一些微调,所以我把长按设计成了细分词(把词语细分成单字),而拖拽的交互留给了排序功能(需要切换排序开关)。

效果图

如何使用Android的拖拽接口实现拖拽功能-JEESNS
长按细分词,拖拽排序

也可以下载全能分词体验

实现原理和步骤

其实Android已经提供了拖拽功能的接口,在API level 11以上的View类中,直接调用startDrag()方法或者startDragAndDrop()即可。

如何使用Android的拖拽接口实现拖拽功能-JEESNS
View.startDrag()


渣翻一下:

public final boolean startDrag(ClipData data, DragShadowBuilder shadowBuilder,
                                   Object myLocalState, int flags) 
开始一个拖拽操作。

调用这个方法时,会将一个View.DragShadowBuilder对象传递给系统。

系统将调用这个View.DragShadowBuilder对象的onProvideShadowMetrics(Point, Point)方法来获取拖拽阴影的metrics,
再调用其onDrawShadow(Canvas)方法来绘制拖拽阴影。

之后,系统开始拖拽操作,并将拖拽事件(drag events)发送给你应用中所有visible的View对象。

拖拽事件是被发送到View对象的drag listener或者onDragEvent()方法。
drag listener和onDragEvent()方法接收的参数都是一个DragEvent对象,
对这个DragEvent对象执行getAction()方法的结果是ACTION_DRAG_STARTED。

startDrag()方法可以在任何attacked的View对象上调用,
而不需要是View.DragShadowBuilder使用的View对象,也不需要与被拖拽的View有任何关系。

整个拖拽过程中涉及到的类只有三个:ClipData,DragShadowBuilder和OnDragListener,步骤只有如下两步:

1. 设置拖拽数据,并开始拖拽

ClipData clipData = ClipData.newPlainText(lable, text);//这只是其中一种方式,还可以传递更丰富的数据
View.DragShadowBuilder myShadow = new DragShadowBuilder(view);
view.startDrag(clipData, myShadow, null, 0);

2. 在需要接收拖拽的View上设置监听

anotherView.setOnDragListener(new OnDragListener() {
    @Override
    public boolean onDrag(View v, DragEvent event) {        
        doSomething();
        return true;//true means consumed
    }
});

看完上面的介绍是不是发现实现拖拽操作很简单呢?没错,借助系统方法,我们需要做的工作极少。

源码

完整代码参见Bigbang项目的BigBangLayout类的实现,拖拽的部分从initView()方法和onTouchEvent()方法看起即可。

帖子评论

关注 / 粉丝

我无话可说