ViewDragHelper使用五步法

weixin_33724059發表於2018-05-07
2742735-20948d3a133c7b3d.jpg
victory loves preparation.jpg

引言

今天給大家帶來的是一個小玩意,ViewDragHelper

它是22.1的時候加入到android的支援包中的,我們先來看下官網的解釋

ViewDragHelper is a utility class for writing custom ViewGroups. It offers a number of useful operations and state tracking for allowing a user to drag and reposition views within their parent ViewGroup.

先翻譯一下啦

ViewDragHelper是為自定義組合控制元件而提供的一個高效的一個類,它針對使用者對控制元件的拖拽、定位等操作提供了一系列“操作”和“狀態監聽”的功能

恩,其實說白了,ViewDragHelper是針對於Scroller而封裝的一個實用類,我們先來了解下這個類怎麼使用吧

總體來說,ViewDragHelper的實用相對於Scroller來說更加簡單、易用,因為畢竟是google工程師為方便android開發者而提供的實用類啊~~

我們來看一下

操作步驟

1、在ViewGroup中初始化ViewDragHelper,因為這個類是針對於ViewGroup控制裡面子view的,所以需要在ViewGroup中去實用哦

初始化方法:

ViewDragHelper.create(this, callback);

第一個引數即為viewgroup本身,而callback是viewdraghelper

先看下英文註釋
A Callback is used as a communication channel with the ViewDragHelper back to the parent view using it. on*methods are invoked on siginficant events and several accessor methods are expected to provide the ViewDragHelper with more information about the state of the parent view upon request. The callback also makes decisions governing the range and draggability of child views.
這個回撥是ViewDragHelper與控制元件溝通的橋樑,callback中的方法會在一些view滑動(拖動)等重要的事件上會被呼叫起來,這個回撥還決定了子view的是否可拖動,或者拖動的範圍

額,翻譯的很渣渣,不過看起來知道這個callback很膩害、很重要就好了,稍後我們細聊這個callback

2、處理攔截事件,將攔截事件交給ViewDragHelper去處理,即重寫onInterceptTouchEvent方法

 @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
      //即交給viewDragHelper去處理攔  截事件(固定寫法)
      return viewDragHelper.shouldInterceptTouchEvent(ev);
  }

3、攔截事件給了還不行,還得把touch事件給了

@Override
public boolean onTouchEvent(MotionEvent event) {
   //讓viewDragHelper去處理touch事件(固定寫法)
    viewDragHelper.processTouchEvent(event);   
    return true;
}

4、重寫ComputeScroll()方法,因為viewDragHelper內部是通過Scroller類實現的滑動,所以需要重寫computeScroll來實現控制元件的平滑滾動 ,不過也基本上是固定寫法

@Override
public void computeScroll() {
        //意思是讓viewDragHelper全權負責     (固定寫法)
    if (viewDragHelper.continueSettling(true)){
        ViewCompat.postInvalidateOnAnimation(this);
    }
}

5、現在我們來看看上文說的很膩害的callback,不過我給出來這個callback是控制一個button在垂直方向上拖動的,小夥伴可以考慮下怎麼實現水平方向的拖動

   //實現控制元件拖動的核心
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
    @Override
    public boolean tryCaptureView(View child, int pointerId) {

        //想讓那個控制元件進行滑動,則對那個控制元件進行檢測,本功能由於指向實現一個mView自己的滑動,所以這樣寫
        return mView == child;
    }

    //控制水平方向的位置滑動
    @Override
    public int clampViewPositionHorizontal(View child, int left, int dx) {
        //返回值是滑動的距離,返回0則表示在這個方向上不做滑動
        return 0;//表示水平方向上不滑動
    }

    //控制垂直方向上的位置滑動
    @Override
    public int clampViewPositionVertical(View child, int top, int dy) {
        //top表示的是垂直方向的上的 子view的移動距離,dy表示的是相較於上一次的增量,這裡直接返回top
        return top;
    }

    //解決當子控制元件可點選,不能拖拽(這個是解決水平方向不可拖拽的)
   @Override
    public int getViewHorizontalDragRange(View child) {
        return mView == child ? child.getWidth() : 0;
    }

    //解決當子控制元件可點選,不能拖拽(這個是解決垂直方向不可拖拽的)
    @Override
    public int getViewVerticalDragRange(View child) {
        return mView == child ? child.getHeight() : 0;
    }

ok,註釋都做好了,不過我做的是垂直方向的,水平方向的

ok,上邊的5步走完之後,我們就能通過viewdragHelper去實現viewgroup中的子view去滑動了。
我們來看看效果圖吧
拖拽button在垂直方向上滑動


2742735-2fc48a51abeaa9fe.gif
ViewDragHelper.gif

滑動的很快 ,大致意思就是這樣吧
接下來,貼出全部程式碼啦

首先是
MyFrameLayout


2742735-e5ecffacc116f9be.png
MyFrameLayout01.png

2742735-1e7c3e89711fdede.png
MyFrameLayout02.png

ok,接下來,看看佈局吧
activity_main.xml


2742735-e10a9eea6322a19b.png
activity_main.png

MainActivity


2742735-b8bdfa7a23191ed8.png
MainActivity.png

ok,先介紹到這裡吧,感興趣的同學可以試一試哦~~
晚安啦

相關文章