ViewDragHelper使用

ViewDragHelper API

ViewDragHelper場景:

ViewDragHelper解決了Android中手勢處理過于復雜的問題,在DrawerLayout出現(xiàn)之前,側滑菜單都是由第三方開源代碼實現(xiàn)的,其中著名的當屬MenuDrawer,MenuDrawer重寫onTouchEvent方法來實現(xiàn)側滑效果,代碼量很大,實現(xiàn)邏輯也需要很大的耐心才能看懂。

ViewDragHelper初始化

ViewDragHelper的實例是通過靜態(tài)工廠方法創(chuàng)建的:ViewDragHelper.create(this,1.0f,newViewDragHelper.Callback()

第一個就是當前的ViewGroup,第二個sensitivity,設置touchSlop(一個很小的距離值,只有在前后兩次觸摸點的距離超過mTouchSlop的值時,我們才把這兩次觸摸算作是“滑動”),sensitivity越大,mTouchSlop越小,對滑動的檢測就越敏感,第三個在用戶的觸摸過程中會回調(diào)相關方法

ViewDragHelper用法

繼承ViewGroup或子類

重寫onInterceptTouchEvent

調(diào)用return mDragHelper.shouldInterceptTouchEvent(ev);表示是否應該攔截當前的事件

重寫onTouchEvent

調(diào)用mDragger.processTouchEvent(event);return true;通過processTouchEvent處理事件

Callback方法

tryCaptureView 返回true表示捕捉view

clampViewPositionHorizontal 處理橫向的拖動

clampViewPositionVertical處理縱向的拖動

上述方法需要重寫,第一個自動顯示重寫,后兩個需要手動重寫,默認返回0

onEdgeDragStarted 表示邊界拖動時回調(diào),如果你想在邊緣滑動的時候根據(jù)滑動距離移動一個子view,調(diào)用mDragHelper.captureChildView方法

onViewReleased?手指釋放的時候回調(diào)

ViewDragHelper實現(xiàn)的方法

setEdgeTrackingEnabled 處理滑動邊緣

settleCapturedViewAt 手指釋放返回指定位置

shouldInterceptTouchEvent?表示是否應該攔截當前的事件

processTouchEvent 處理觸摸事件

ViewDragHelper注意的坑

如果子View不消耗事件,那么整個手勢(DOWN-MOVE*-UP)都是直接進入onTouchEvent,在onTouchEvent的DOWN的時候就確定了captureView。如果消耗事件,那么就會先走onInterceptTouchEvent方法,判斷是否可以捕獲,而在判斷的過程中會去判斷另外兩個回調(diào)的方法:getViewHorizontalDragRange和getViewVerticalDragRange,只有這兩個方法返回大于0的值才能正常的捕獲,如果你用Button測試,或者給TextView添加了clickable = true ,都記得重寫。

方法的大致的回調(diào)順序:

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狀態(tài)),接下來MOVE就直接dragTo了。

而當子View消耗事件的時候,就需要走shouldInterceptTouchEvent,MOVE的時候經(jīng)過一系列的判斷(getViewHorizontalDragRange,clampViewPositionVertical等),才能夠去tryCaptureView。


參考:

ViewDragHelper詳解

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

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容