ViewDragHelper使用

ViewDragHelper API

ViewDragHelper场景:

ViewDragHelper解决了Android中手势处理过于复杂的问题,在DrawerLayout出现之前,侧滑菜单都是由第三方开源代码实现的,其中著名的当属MenuDrawer,MenuDrawer重写onTouchEvent方法来实现侧滑效果,代码量很大,实现逻辑也需要很大的耐心才能看懂。

ViewDragHelper初始化

ViewDragHelper的实例是通过静态工厂方法创建的:ViewDragHelper.create(this,1.0f,newViewDragHelper.Callback()

第一个就是当前的ViewGroup,第二个sensitivity,设置touchSlop(一个很小的距离值,只有在前后两次触摸点的距离超过mTouchSlop的值时,我们才把这两次触摸算作是“滑动”),sensitivity越大,mTouchSlop越小,对滑动的检测就越敏感,第三个在用户的触摸过程中会回调相关方法

ViewDragHelper用法

继承ViewGroup或子类

重写onInterceptTouchEvent

调用return mDragHelper.shouldInterceptTouchEvent(ev);表示是否应该拦截当前的事件

重写onTouchEvent

调用mDragger.processTouchEvent(event);return true;通过processTouchEvent处理事件

Callback方法

tryCaptureView 返回true表示捕捉view

clampViewPositionHorizontal 处理横向的拖动

clampViewPositionVertical处理纵向的拖动

上述方法需要重写,第一个自动显示重写,后两个需要手动重写,默认返回0

onEdgeDragStarted 表示边界拖动时回调,如果你想在边缘滑动的时候根据滑动距离移动一个子view,调用mDragHelper.captureChildView方法

onViewReleased 手指释放的时候回调

ViewDragHelper实现的方法

setEdgeTrackingEnabled 处理滑动边缘

settleCapturedViewAt 手指释放返回指定位置

shouldInterceptTouchEvent 表示是否应该拦截当前的事件

processTouchEvent 处理触摸事件

ViewDragHelper注意的坑

如果子View不消耗事件,那么整个手势(DOWN-MOVE*-UP)都是直接进入onTouchEvent,在onTouchEvent的DOWN的时候就确定了captureView。如果消耗事件,那么就会先走onInterceptTouchEvent方法,判断是否可以捕获,而在判断的过程中会去判断另外两个回调的方法:getViewHorizontalDragRange和getViewVerticalDragRange,只有这两个方法返回大于0的值才能正常的捕获,如果你用Button测试,或者给TextView添加了clickable = true ,都记得重写。

方法的大致的回调顺序:

shouldInterceptTouchEvent:

DOWN:

getOrderedChildIndex(findTopChildUnder)

->onEdgeTouched

MOVE:

getOrderedChildIndex(findTopChildUnder)

->getViewHorizontalDragRange &

getViewVerticalDragRange(checkTouchSlop)(MOVE中可能不止一次)

->clampViewPositionHorizontal&

clampViewPositionVertical

->onEdgeDragStarted

->tryCaptureView

->onViewCaptured

->onViewDragStateChanged

processTouchEvent:

DOWN:

getOrderedChildIndex(findTopChildUnder)

->tryCaptureView

->onViewCaptured

->onViewDragStateChanged

->onEdgeTouched

MOVE:

->STATE==DRAGGING:dragTo

->STATE!=DRAGGING:

onEdgeDragStarted

->getOrderedChildIndex(findTopChildUnder)

->getViewHorizontalDragRange&

getViewVerticalDragRange(checkTouchSlop)

->tryCaptureView

->onViewCaptured

->onViewDragStateChanged

在TextView(clickable=false)的情况下,没有编写getViewHorizontalDragRange方法时,是可以移动的。因为直接进入processTouchEvent的DOWN,然后就onViewCaptured、onViewDragStateChanged(进入DRAGGING状态),接下来MOVE就直接dragTo了。

而当子View消耗事件的时候,就需要走shouldInterceptTouchEvent,MOVE的时候经过一系列的判断(getViewHorizontalDragRange,clampViewPositionVertical等),才能够去tryCaptureView。


参考:

ViewDragHelper详解

Android ViewDragHelper完全解析 自定义ViewGroup神器

你可能感兴趣的:(ViewDragHelper使用)