【记录】记录点滴
【场景】学习官方文档和sample时,实验的内容以及遇到的小坑
【需求】简单实现,基于View.OnDragListener, ViewDragHelper以及GestureDetector(或OnTouchEvent,OnTouchListener)实现拖放View滑动的效果
1. View.OnDragListener
官方文档提供了示例demo,包括实现拖放,自定义拖放时阴影的样式。
如果要实现拖放功能,需要1)创建View.OnDragListener,它是拖放事件的监听器;2)某些View过ViewGroup需要监听拖放事件,并根据操作状态实现需要的效果,因此对这些View设置创建好的View.OnDragListener监听器;3)创建一个View被拖放时的影子,并调用方法表明开始拖放操作。顺序不是固定的,感觉这个顺序比较好理解。
//自定义的拖放监听器,未实现任何操作
class DragerListener implements View.OnDragListener {
@Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
/** 拖拽开始时 */
break;
case DragEvent.ACTION_DRAG_ENTERED:
/** 拖拽进入区域时 */
break;
case DragEvent.ACTION_DRAG_Location:
/** 拖拽进入区域后,仍在区域内拖动时 */
break;
case DragEvent.ACTION_DRAG_EXITED:
/** 离开区域时 */
break;
case DragEvent.ACTION_DROP:
/** 在区域内放开时 */
break;
case DragEvent.ACTION_DRAG_ENDED:
/** 结束时 */
default:
break;
}
return true;
}
}
画一个简单的图说明,假设这是个手机屏幕,黑色圆是需要我们拖拽的View,红色矩形就是需要监听拖放事件并进行响应的区域。 首先创建拖放的监听器,随后仅仅对红色矩形(实际的应用场景中可能是View,也可能是ViewGroup)设置监听器,最后设置黑色圆的拖放阴影,并在适当的场景(如touch,longclick等)下告诉系统,我们开始了拖放操作。
开始拖拽圆时,触发START操作
DragEvent.ACTION_DRAG_STARTED
当拖拽的点(通常是被拖拽的View的中心点)进入到红色的矩形区域后,触发ENTERED操作
DragEvent.ACTION_DRAG_ENTERED
当拖拽的点一直在红色区域内移动时,会不断地触发LOCATION操作
DragEvent.ACTION_DRAG_LOCATION
如果拖拽的点仍在红色区域内时,释放了被拖拽的View,则会触发DROP。因为DROP可以理解为是与区域绑定的,所以一次DROP只会交给一个对象来处理。脑补下,如果左下角还有个蓝色区域也监听了拖放事件,但是我们在红色区域内释放了View,那么只有红色区域的监听器会触发DROP操作
DragEvent.ACTION_DROP
并且在释放后,会触发ENDED操作
DragEvent.ACTION_DRAG_ENDED
另一种情况,如果拖拽的点移动出了区域,那么会触发EXITED操作
DragEvent.ACTION_DRAG_EXITED
到这里,应该可以弄清楚监听器的各操作类型的触发条件了。实现简单的拖拽
按照之前的描述,先自定义监听器,处理各种类型的操作
class DragListener implements View.OnDragListener {
@Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.e("lxy", "ACTION_DRAG_ENTERED");
//这个v就是监听拖拽事件的View,对照上面的图就是红色矩形区域
//拖拽进入区域后,变成蓝色背景
v.setBackgroundColor(Color.BLUE);
break;
case DragEvent.ACTION_DRAG_LOCATION:
Log.e("lxy", "ACTION_DRAG_LOCATION");
break;
case DragEvent.ACTION_DRAG_EXITED:
Log.e("lxy", "ACTION_DRAG_EXITED");
//拖拽出区域后,恢复成红色背景
v.setBackgroundColor(Color.RED);
break;
case DragEvent.ACTION_DROP: