Android拖拽助手ViewDragHelper的創(chuàng)建與使用實(shí)例
前言
在項(xiàng)目中,我們經(jīng)常自定義ViewGroup,有時(shí)候需要拖拽它的子View,讓其運(yùn)動(dòng),一般情況下如果我們手動(dòng)處理各種滑動(dòng)事件,非常麻煩,谷歌給我們提供了一個(gè)輔助類ViewDragHelper,ViewDragHelper給我們提供了很多拖拽相關(guān)的方法以及狀態(tài)跟蹤。
創(chuàng)建實(shí)例
ViewDragHelper.create(vp, callback);
ViewDragHelper的創(chuàng)建比較簡單,它的構(gòu)造函數(shù)是私有的,只能通過create()方法創(chuàng)建,第一個(gè)參數(shù)是一個(gè)ViewGroup,也就是需要使用ViewDragHelper的自定義View,第二個(gè)參數(shù)callback,提供了很多拖拽相關(guān)的回調(diào)。
ViewDragHelper.Callback
下面是幾個(gè)常用的方法
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() { public boolean tryCaptureView(View child, int pointerId) public int getViewHorizontalDragRange(View child) public int clampViewPositionHorizontal(View child, int left, int dx) public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) public void onViewReleased(View releasedChild, float xvel, float yvel)
- tryCaptureView返回一個(gè)boolean,用戶判斷是否捕獲當(dāng)前view的觸摸事件
- getViewHorizontalDragRange獲取child水平方向的拖拽范圍
- clampViewPositionHorizontal控制child在水平方向的移動(dòng),我們可以通過dx修正left的值,返回值表示我們真正想讓child的left變成的值
- clampViewPositionVertical和水平方向類似
- onViewPositionChanged 當(dāng)child位置改變時(shí)候的回調(diào)
- onViewReleased當(dāng)拖拽的view釋放的時(shí)候回調(diào)
使用
自定義一個(gè)簡單的側(cè)拉菜單,該菜單有兩個(gè)子View,一個(gè)主界面,一個(gè)側(cè)邊菜單界面
首先自定義一個(gè)ViewGroup并初始化ViewDragHelper
public class SlideMenu extends FrameLayout{ private void init(){ viewDragHelper = ViewDragHelper.create(this, callback); } }
然后重寫onInterceptTouchEvent和onTouchEvent,將這兩個(gè)方法的處理邏輯交給ViewDragHelper
public boolean onInterceptTouchEvent(MotionEvent ev) { return viewDragHelper.shouldInterceptTouchEvent(ev); } public boolean onTouchEvent(MotionEvent event) { viewDragHelper.processTouchEvent(event); return true; }
實(shí)現(xiàn)ViewDragHelper.Callback,重寫tryCaptureView,在當(dāng)前Layout中兩個(gè)子VIew都需要滑動(dòng),所以直接返回true.
public boolean tryCaptureView(View child, int pointerId) { return true; }
先限制一下橫向滑動(dòng)范圍,給一個(gè)最大值
public int getViewHorizontalDragRange(View child) { return (int) dragRange; }
主界面在滑動(dòng)過程中,我們需要控制下它在水平方向的移動(dòng)距離
public int clampViewPositionHorizontal(View child, int left, int dx) { if(child==mainView){ if(left<0)left=0;//限制mainView的左邊 if(left>dragRange)left=(int) dragRange;//限制mainView的右邊 } return left; }
在滑動(dòng)過程中,根據(jù)拖拽回調(diào)重新對(duì)側(cè)拉菜單和主界面布局,不斷刷新他們的位置信息,這里簡單起見,讓側(cè)拉菜單固定,只是主界面滑動(dòng)。
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { if(changedView==menuView){ menuView.layout(0, 0, menuView.getMeasuredWidth(),menuView.getMeasuredHeight()); int newLeft = mainView.getLeft()+dx; if(newLeft<0)newLeft=0; if(newLeft>dragRange)newLeft=(int) dragRange;mainView.layout(newLeft,mainView.getTop()+dy,newLeft+mainView.getMeasuredWidth(),mainView.getBottom()+dy); } }
當(dāng)手指抬起釋放view的時(shí)候,可能我們只是拖拽了一點(diǎn),這時(shí)候我們需要根據(jù)當(dāng)前拖拽的信息決定是打開菜單還是關(guān)閉菜單。
public void onViewReleased(View releasedChild, float xvel, float yvel) { if(mainView.getLeft()<dragRange/2){ //在左半邊 close(); }else { //在右半邊 open(); } }
對(duì)于view的滑動(dòng)ViewDragHelper也提供了smoothSlideViewTo方法,所以close和open方法就很簡單
public void close() { viewDragHelper.smoothSlideViewTo(mainView,0,mainView.getTop()); ViewCompat.postInvalidateOnAnimation(SlideMenu.this); } public void computeScroll() { if(viewDragHelper.continueSettling(true)){ ViewCompat.postInvalidateOnAnimation(SlideMenu.this); } }
然后還可以提供一些拖拽狀態(tài)回調(diào),比如拖拽完成,拖拽中等狀態(tài),這些比較簡單,直接在onViewPositionChanged中處理就可以了。
最后看一下效果
總結(jié)
到此這篇關(guān)于Android拖拽助手ViewDragHelper的創(chuàng)建與使用的文章就介紹到這了,更多相關(guān)Android拖拽助手ViewDragHelper內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在啟動(dòng)欄制作android studio啟動(dòng)圖標(biāo)
這篇文章主要介紹了在啟動(dòng)欄制作android studio啟動(dòng)圖標(biāo)的相關(guān)知識(shí),需要的朋友可以參考下2018-03-03Android切換至SurfaceView時(shí)閃屏(黑屏閃一下)以及黑屏移動(dòng)問題的解決方法
本文主要介紹了Android切換至SurfaceView時(shí)閃屏(黑屏閃一下)以及黑屏移動(dòng)問題的解決方法。具有一定的參考作用,下面跟著小編一起來看下吧2017-01-01Android通知欄前臺(tái)服務(wù)的實(shí)現(xiàn)
這篇文章主要介紹了Android通知欄前臺(tái)服務(wù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Android實(shí)現(xiàn)監(jiān)聽音量的變化
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)監(jiān)聽音量的變化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05Android中RecyclerView上拉下拉,分割線,多條目的實(shí)例代碼
這篇文章主要介紹了Android中RecyclerView上拉下拉,分割線,多條目的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-01-01Ionic2創(chuàng)建App啟動(dòng)頁左右滑動(dòng)歡迎界面
使用Ionic2創(chuàng)建應(yīng)用非常簡單,只需在V1的命令后跟上--v2即可.這篇文章主要介紹了Ionic2創(chuàng)建App啟動(dòng)頁左右滑動(dòng)歡迎界面的相關(guān)資料,需要的朋友可以參考下2016-10-10