转载注明出处:简书-十个雨点
简介
拖拽操作在现在的智能手机中并不少见,老罗的OneStep更是把拖拽做成了一种令人拍手叫绝的交互方式。在锤子手机原生的Bigbang中,普通拖动是多选文字,长按选中的文字并拖动是触发OneStep的分享功能。而我在模仿Bigbang的时候,觉得用户可能需要对文字进行一些微调,所以我把长按设计成了细分词(把词语细分成单字),而拖拽的交互留给了排序功能(需要切换排序开关)。
效果图
也可以下载全能分词体验
实现原理和步骤
其实Android已经提供了拖拽功能的接口,在API level 11以上的View类中,直接调用startDrag()方法或者startDragAndDrop()即可。
渣翻一下:
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()方法看起即可。