ViewDragHelper到底怎么用(一)?

開(kāi)發(fā)中棘伴,我們經(jīng)常會(huì)有拖動(dòng)View的一些效果,比如

  • 1.跟著手指移動(dòng)的小球
  • 2.抽屜效果
  • 3.手指撥動(dòng)后就返回上一個(gè)頁(yè)面的效果

這些效果如果完全靠自己自定義ViewGroup屁置,然后重寫onTouchEvent以及onInterceptTouchEvent來(lái)完成會(huì)非常的麻煩焊夸,挑戰(zhàn)性很大。但是假如有了ViewGragHelper的幫助蓝角,會(huì)變得簡(jiǎn)單很多阱穗。所以,可以看到ViewDragHelper一般出現(xiàn)在自定義ViewGroup中使鹅,幫助我們快速的處理一些手勢(shì)相關(guān)的效果揪阶。
先上圖看這個(gè)例子:

image.png
  • 第一個(gè)View,就是演示簡(jiǎn)單的移動(dòng)
  • 第二個(gè)View患朱,演示除了移動(dòng)后鲁僚,松手自動(dòng)返回到原本的位置。(注意你拖動(dòng)的越快裁厅,返回的越快)
  • 第三個(gè)View冰沙,邊界移動(dòng)時(shí)對(duì)View進(jìn)行捕獲。

實(shí)現(xiàn)步驟

1.自定義ViewGroup执虹,繼承LinearLayout

public class VDHLayout extends LinearLayout

2.在構(gòu)造方法中創(chuàng)建ViewGragHelper對(duì)象拓挥,同時(shí)設(shè)置屏幕左邊緣可以被追蹤:

mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            .... //這里面會(huì)覆寫很多方法
            ....//這里面會(huì)覆寫很多方法
            ....//這里面會(huì)覆寫很多方法
            ....//這里面會(huì)覆寫很多方法
        });
mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);

這里的第二參數(shù)是1.0f代表sensitivity, 主要用于設(shè)置touchslop

3.要想把一系列的事件交給ViewDragHelper處理的話袋励,需要重寫以下方法:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
   return mDragger.shouldInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    mDragger.processTouchEvent(event);
    return true;
}

4.這一步就是要override callback方法撞叽,來(lái)實(shí)現(xiàn)對(duì)ViewGroup下的子View的控制。

4.1獲取子View的對(duì)象
@Override
 protected void onFinishInflate() {
      super.onFinishInflate();
      mDragView = getChildAt(0);
      mAutoBackView = getChildAt(1);
     mEdgeTrackerView = getChildAt(2);
 }
4.2由于第二個(gè)View當(dāng)被拖動(dòng)以后需要回到原來(lái)的位置插龄,所以需要記錄當(dāng)前的位置, 覆寫onLayout方法
private Point mAutoBackOriginPos = new Point();
@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        mAutoBackOriginPos.x = mAutoBackView.getLeft();
        mAutoBackOriginPos.y = mAutoBackView.getTop();
    }
4.3由于第三個(gè)View在手指觸摸它的時(shí)候不會(huì)移動(dòng)科展,所以
@Override
 public boolean tryCaptureView(View child, int pointerId) {
                //mEdgeTrackerView禁止直接移動(dòng)
                return child == mDragView || child == mAutoBackView;
}

也就是需要觸發(fā)touch事件的view需要覆寫這個(gè)方法均牢,并且要指定childview

4.4手指釋放后,彈回原來(lái)的位置
//手指釋放的時(shí)候回調(diào)
 @Override
 public void onViewReleased(View releasedChild, float xvel, float yvel) {
         //mAutoBackView手指釋放時(shí)可以自動(dòng)回去
         if (releasedChild == mAutoBackView) {
               mDragger.settleCapturedViewAt(mAutoBackOriginPos.x, mAutoBackOriginPos.y);
               invalidate();
         }
 }

注意由于這里使用的是invalidate方法才睹,所以需要重寫

  @Override
   public void computeScroll() {
       if (mDragger.continueSettling(true)) {
           invalidate();
       }
   }
4.5指定邊界能拖動(dòng)的View
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
      mDragger.captureChildView(mEdgeTrackerView, pointerId);
}
4.6當(dāng)想要控制View的移動(dòng)邊界的時(shí)候徘跪,可以:
           @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                //只在ViewGroup的內(nèi)部移動(dòng)
                final int leftBound = getPaddingLeft();
                final int rightBound = getWidth() - child.getWidth() - getPaddingRight();
                //這個(gè)寫法不懂
                //我希望只在ViewGroup的內(nèi)部移動(dòng)甘邀,
                // 即:最小>=paddingleft,最大<=ViewGroup.getWidth()-paddingright-child.getWidth垮庐。
                final int newLeft = Math.min(Math.max(left, leftBound), rightBound);

                return newLeft;
            }

            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return top;
            }

到此松邪,我們列一下所有的Callback方法,看看還有哪些沒(méi)用過(guò)的:

  • onViewDragStateChanged

當(dāng)ViewDragHelper狀態(tài)發(fā)生變化時(shí)回調(diào)(IDLE,DRAGGING,SETTING[自動(dòng)滾動(dòng)時(shí)])

  • onViewPositionChanged

當(dāng)captureview的位置發(fā)生改變時(shí)回調(diào)

  • onViewCaptured

當(dāng)captureview被捕獲時(shí)回調(diào)
onViewReleased 已用

  • onEdgeTouched

當(dāng)觸摸到邊界時(shí)回調(diào)哨查。

  • onEdgeLock

true的時(shí)候會(huì)鎖住當(dāng)前的邊界逗抑,false則unLock。
onEdgeDragStarted 已用

  • getOrderedChildIndex

改變同一個(gè)坐標(biāo)(x,y)去尋找captureView位置的方法寒亥。(具體在:findTopChildUnder方法中)
getViewHorizontalDragRange 已用

getViewVerticalDragRange 已用
tryCaptureView 已用
clampViewPositionHorizontal 已用
clampViewPositionVertical 已用
ok邮府,至此所有的回調(diào)方法都有了一定的認(rèn)識(shí)。

5.項(xiàng)目源碼
源碼參考我的github地址

參考文章:

http://blog.csdn.net/lmj623565791/article/details/46858663

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溉奕,一起剝皮案震驚了整個(gè)濱河市褂傀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌加勤,老刑警劉巖仙辟,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鳄梅,居然都是意外死亡叠国,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門卫枝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)煎饼,“玉大人,你說(shuō)我怎么就攤上這事校赤∵壕粒” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵马篮,是天一觀的道長(zhǎng)沾乘。 經(jīng)常有香客問(wèn)我,道長(zhǎng)浑测,這世上最難降的妖魔是什么翅阵? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮迁央,結(jié)果婚禮上掷匠,老公的妹妹穿的比我還像新娘。我一直安慰自己岖圈,他們只是感情好讹语,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蜂科,像睡著了一般顽决。 火紅的嫁衣襯著肌膚如雪短条。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天才菠,我揣著相機(jī)與錄音茸时,去河邊找鬼。 笑死赋访,一個(gè)胖子當(dāng)著我的面吹牛可都,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播进每,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼汹粤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了田晚?” 一聲冷哼從身側(cè)響起嘱兼,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贤徒,沒(méi)想到半個(gè)月后芹壕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡接奈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年踢涌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片序宦。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡睁壁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出互捌,到底是詐尸還是另有隱情潘明,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布秕噪,位于F島的核電站钳降,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏腌巾。R本人自食惡果不足惜遂填,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望澈蝙。 院中可真熱鬧吓坚,春花似錦、人聲如沸灯荧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至客税,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撕贞,已是汗流浹背更耻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捏膨,地道東北人秧均。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像号涯,于是被迫代替她去往敵國(guó)和親目胡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容