用途
ViewDragHelper类的设计决定了其适用于被包含在一个自定义ViewGroup之中,而不是对任意一个布局上的视图容器使用ViewDragHelper。在自定义的ViewGroup中,主要是帮助我们处理对子控件的拖动操作。ViewDragHelper也是framework中不为人知却非常有用的一个工具。与GestureDetector相比,ViewDragHelper优势体现在与拖动相关的手势分析方面。
原理分析
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
/**
* 如果childrenView消耗掉事件,那么就会先走onInterceptTouchEvent方法,判
* 断是否可以捕获,而在判断的过程中会去判断另外两个回调的方法:getViewHorizontalDragRange
* 和getViewVerticalDragRange,只有这两个方法返回大于0的值才能正常的捕获。
*/
return mDragger.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//处理事件会用到ViewDragHelper.Callback中的回调
mDragger.processTouchEvent(event);
return true;
}
onTouchEvent()中很明显的展示了,对于触摸事件的分析交给ViewDragHelper来帮我处理,它可以帮我们解析拖动的触摸事件,处理的逻辑我们可以ViewDragHelper.Callback()中分析处理。
应用场景
仿Youtobe拖拽效果实现
仿DrawerLayout实现侧滑
主要方法介绍
ViewDragHelper相关方法介绍
mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
设置可以跟踪的触摸边界,值有EDGE_LEFT , EDGE_RIGHT , EDGE_TOP ,EDGE_BOTTOM
ViewDragHelper.Callback中相关回调函数介绍
public boolean tryCaptureView(View child, int pointerId)
确定是否对child进行捕捉(拖动)
public int clampViewPositionHorizontal(View child, int left, int dx)
水平方向上对拖动的空间进行控制
public int clampViewPositionVertical(View child, int top, int dy)
垂直方向上对拖动的空间进行控制
public void onEdgeTouched(int edgeFlags, int pointerId)
当设置的触摸边界被触摸到时出发
public void onEdgeDragStarted(int edgeFlags, int pointerId)
开始边界触摸,这里可以绕过tryCaptureView(),可以手动制定要拖动的控件,如mDragHelper.captureChildView(mDragView2, pointerId);
当childView可以消耗事件的时候,事件的就不会传递到ViewGroup的onTouchEvent()中,所以ViewDragHelper就不会去解析拖动的事件,要想让其解析,则需要重写以下两个回调函数
public int getViewHorizontalDragRange(View child)
childView横向的移动的范围
public int getViewVerticalDragRange(View child)
childView纵向的移动的范围
public boolean onEdgeLock()
返回true的时候会锁住当前的边界,false则unLock
public int onViewCaptured()
当captureView被捕获时回调
public int onViewDragStateChanged()
当ViewDragHelper状态发生变化时回调(IDLE,DRAGGING,SETTING[自动滚动时])
public int onViewPositionChanged()
当captureview的位置发生改变时回调