RecyclerView滑動距離計算

NathansLiu發表於2017-12-28

RecyclerView滑動距離計算

二話不說,上圖先!

RecyclerView已經出來許久了,估計現在沒多少人使用ListView或者GridView了吧?

這篇文章講解如何計算寬高相同或不同Item的RecyclerView滑動距離,所謂的滑動距離意思如下圖。

RecyclerView滑動距離計算

大概思路就是先得出正在移出螢幕Item的position,再得出該Item的寬或高,再得出該Item還有多少部分未移出螢幕,拿position乘寬或者高減去未移出螢幕的距離,就可以算出滑動的距離了(๑•ᴗ•๑)

先看下定義的變數和常量

//豎著
private static final int MANAGER_LINEAR_VERTICAL = 0;
//橫著一行
private static final int MANAGER_LINEAR_HORIZONTAL = 1;
//Grid 豎著
private static final int MANAGER_LINEAR_GRIDVIEW_VERTICAL = 2;
//Grid 橫著
private static final int MANAGER_LINEAR_GRIDVIEW_HORIZONTAL = 3;
//豎著不同
private static final int MANAGER_LINEAR_VERTICAL_ = 4;
//橫著不同
private static final int MANAGER_LINEAR_HORIZONTAL_ = 5;
//形態變數
private int intType = 0;
//item的寬/高
private int itemW;
private int itemH;
private int iResult;
//存放item寬或高
private Map<Integer, Integer> mMapList = new HashMap<>();
private int iposition;複製程式碼

Item佈局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_tk"/>
    <TextView
        android:id="@+id/tv_position"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/iv"
        android:layout_alignTop="@+id/iv"
        android:background="@color/colorPrimary"
        android:textColor="#e5e5e6"
    />
</RelativeLayout>複製程式碼

一、計算寬高相同Item

//該方法用於監聽mRecyclerView的滑動事件
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
    }
});複製程式碼

在上面監聽中呼叫下面計算方法,可計算出VERTICAL豎著佈局的滑動距離

//找到即將移出螢幕Item的position,position是移出螢幕item的數量
int position = linearLayoutManager.findFirstVisibleItemPosition();
//根據position找到這個Item
View firstVisiableChildView = linearLayoutManager.findViewByPosition(position);
//獲取Item的高
int itemHeight = firstVisiableChildView.getHeight();
//算出該Item還未移出螢幕的高度
int itemTop = firstVisiableChildView.getTop();
//position移出螢幕的數量*高度得出移動的距離
int iposition = position * itemHeight;
//減去該Item還未移出螢幕的部分可得出滑動的距離
iResult = iposition - itemTop;複製程式碼

若是HORIZONTAL橫著的RecyclerView則需要稍加改動呼叫下面方法就能計算出滑動距離因為是橫著的所以要拿到item的寬,用getRight()方法算出未移出螢幕的距離,但橫著的RecyclerView取到的第一個Item Position為零,所以隨後算總距離的時候要加上一個Item的寬度

//找到即將移出螢幕Item的position,position是移出螢幕item的數量
int position = linearLayoutManager.findFirstVisibleItemPosition();
//根據position找到這個Item
View firstVisiableChildView = linearLayoutManager.findViewByPosition(position);
//獲取Item的寬
int itemWidth = firstVisiableChildView.getWidth();
//算出該Item還未移出螢幕的高度
int itemRight = firstVisiableChildView.getRight();
//position移出螢幕的數量*高度得出移動的距離
int iposition = position * itemWidth;
//因為橫著的RecyclerV第一個取到的Item position為零所以計算時需要加一個寬
iResult = iposition - itemRight + itemWidth;複製程式碼

二、計算Grid排列相同Item

豎著的Grid,註釋很認真的寫了(⊙o⊙),大部分還是一樣的

//得出spanCount幾列或幾排
int itemSpanCount = gridLayoutManager.getSpanCount();
//得出的position是一排或一列總和
int position = gridLayoutManager.findFirstVisibleItemPosition();
//需要算出才是即將移出螢幕Item的position
int itemPosition = position / itemSpanCount ;
//因為是相同的Item所以取那個都一樣
View firstVisiableChildView = gridLayoutManager.findViewByPosition(position);
int itemHeight = firstVisiableChildView.getHeight();
int itemTop = firstVisiableChildView.getTop();
int iposition = itemPosition * itemHeight;
iResult = iposition - itemTop;複製程式碼

橫著的Grid大家可以下Demo看一下,也是有註釋的

三、計算不同Item

思路:用Map按Position記錄了每個Item的寬或高,通過findFirstVisibleItemPosition()方法動態計算滑動距離

public int unlikeVertical() {
    int itemWH = 0;
    int itemTR = 0;
    int distance = 0;
    int position = linearLayoutManager.findFirstVisibleItemPosition();
    View firstVisiableChildView = linearLayoutManager.findViewByPosition(position);
    //判斷是橫著還是豎著,得出寬或高
    if (intType == MANAGER_LINEAR_VERTICAL_) {
        itemWH = firstVisiableChildView.getHeight();
    } else if (intType == MANAGER_LINEAR_HORIZONTAL_) {
        itemWH = firstVisiableChildView.getWidth();
    }
    //一層判斷mMapList是否為空,若不為空則根據鍵判斷保證不會重複存入
    if (mMapList.size() == 0) {
        mMapList.put(position, itemWH);
    } else {
        if (!mMapList.containsKey(position)) {
            mMapList.put(position, itemWH);
            Log.d("poi", mMapList + "");
        }
    }
    //判斷是橫著還是豎著,得出未滑出螢幕的距離
    if (intType == MANAGER_LINEAR_VERTICAL_) {
        itemTR = firstVisiableChildView.getTop();
    } else if (intType == MANAGER_LINEAR_HORIZONTAL_) {
        itemTR = firstVisiableChildView.getRight();
    }
    //position為動態獲取,目前螢幕Item位置
    for (int i = 0; i < position; i++) {
        //iposition移出螢幕的距離
        iposition = iposition + mMapList.get(i);
    }
    //根據型別拿iposition減未移出Item部分距離,最後得出滑動距離
    if (intType == MANAGER_LINEAR_VERTICAL_) {
        distance = iposition - itemTR;
    } else if (intType == MANAGER_LINEAR_HORIZONTAL_) {
        distance = iposition - itemTR + itemWH;
    }
    //item寬高
    itemW = firstVisiableChildView.getWidth();
    itemH = firstVisiableChildView.getHeight();
    //歸零
    iposition = 0;
    return distance;
}
複製程式碼

Demo地址:github.com/NathansLiu/…

My JianShu:www.jianshu.com/u/ae7a687f5…

寫完啦!


RecyclerView滑動距離計算



相關文章