1. 程式人生 > >Andriod群英傳-Android Scroll 分析學習筆記

Andriod群英傳-Android Scroll 分析學習筆記

1.滑動效果的產生

1.1.Android座標系

Android座標系是以螢幕的左上角為座標系原點,從原點水平向右為X軸正方向,從原點豎直向下為Y軸正方向。
在觸控事件中,通過getRawX( ) , etRawY( )可以獲得對應的座標。

1.2.檢視座標系

不同於上面的Android座標系,這個座標系是以該檢視控制元件的左上角為原點,對應的X,Y軸和上面的同樣原理。
不同於上面,這裡在觸控事件中,需要通過getX( ) ,getY( )獲得檢視座標系中的座標。

1.3.觸控事件–MotionEvent

幾種常用到觸控動作:
1. ACTION_DOWN:單點觸控按下動作
2. ACTION_UP:單點觸控離開動作
3. ACTION_MOVE:單點觸控移動動作
4. ACTION_CANCEL:觸控動作取消
5. ACTION_OUTSIDE:觸控動作超出邊界
6. ACTION_POINTER_DOWN:多點觸控按下動作
7. ACTION_POINTER_UP:多點離開動作

常用的獲取座標值、相對距離等方法:
- View提供的獲取座標方法:
1. getTop():獲取到View自身頂邊到其父佈局頂邊的距離;
2. getLeft():獲取到View自身左邊到其父佈局左邊的距離;
3. getRight():獲取到View自身右邊到其父佈局右邊的距離;
4. getBottom():獲取到View自身頂部到其父佈局頂邊的距離;
- MotionEvent提供的方法:
1. getX():獲取到點選事件距離控制元件左邊的距離;
2. getY():獲取到點選事件距離控制元件頂部的距離;
3. getRawX():獲取到點選事件距離整個螢幕左邊的距離,為絕對座標;
4. getRawY():獲取到點選事件距離整個螢幕右邊的距離,為絕對座標。

2.七種實現滑動的方法

思路:當觸控View的時候,記錄當前的觸控點,然後手指移動止嘔胡,記錄下移動後的距離,通過計算比較兩次座標點的偏移量,來修改View的座標,從而實現滑動。

2.1.layout方法

就是在View的OnTouchEvent方法中,通過在ACTION_MOVE事件中動態的呼叫onLayout方法來實現View的滑動。

2.2.offsetLeftAndRight()與offsetTopAndBottom()

效果和onLayout一樣,只是這個是計算一個偏移量之後,呼叫系統提供的此API。

2.3.LayoutParams

這裡通過計算出來的offset來動態的改變layoutparams的margin值,這裡最好用ViewGroup.MarginLayoutParams,這樣就不用過多的考慮父佈局到底是LinearLayout還是其他了。

2.4.scrollTo和scrollBy

to和by的區別,顧名思義,一個是移動到某一個點,一個是便宜一點的距離。
另外,scrollTo和scrollBy移動的是View的Content,也就是說讓View的內容移動。如果是ViewGroup,那麼移動的是它的子View,如果是View,那麼移動的就是他的內容了(比如,TextView就是移動的文字內容…)。
最後一點,就是scrollBy方法的偏移量移動的是父佈局,所以要想看起來是控制元件在動,需要設定偏移量為負值即可。

2.5.Scroller

使用Scroller類的三個步驟:
1. 初始化,通過構造方法傳入一個Context物件建立一個Scroller物件;
2. 重寫computeScroll()方法,實現模擬互動,系統繪製View的時候,會在onDraw()方法中呼叫此方法:此方法實際上就是一個scrollTo方法,就是通過這個Scroller物件把偏移量轉換成一個個小距離,進行順滑的實現。另外需要通過呼叫View的invalidate()方法主動的實現迴圈繪圖;
3. startScroll開啟模擬過程

2.6.屬性動畫

採用位移動畫可以實現滾動效果。

2.7.ViewDragHelper(重點)

viewdraghelper實現;

1.初始化ViewDragHelper:

mViewDragHelper=ViewDragHelper.create(this,callback),呼叫靜態方法實現初始化,第一個引數傳入的是一個ViewGroup,第二個傳入的是一個非常重要的回撥,這個後面會深入研究;

2.攔截事件:

攔截ViewGroup的onInterceptTouchEventonTouchEvent

3.處理computScroll():

一般都是這個模板

    @Override
    public void computeScroll() {
        if (dragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

4.處理回撥callback:

ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {}

裡面幾個主要的回撥方法:

public boolean tryCaptureView(View child, int pointerId) {}:
設定何時開始檢測觸控事件,比如指定只有觸控的某一個child的時候才會檢測。

public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {}:
此時已經開始滾動,這個裡面可以進行一些檢視位置的改變,動畫效果的新增等。

public int getViewVerticalDragRange(View child) {}:
設定垂直方向拖動的範圍。

public int clampViewPositionVertical(View child, int top, int dy) {}:處理垂直方向的滑動。

public void onViewReleased(View releasedChild, float xvel, float yvel) {}:
拖動結束後的處理。