RecyclerView滑動距離計算


二話不說,上圖先!android

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

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


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

先看下定義的變量和常量
ide

//豎着
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>複製代碼

1、計算寬高相同Itemui

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

在上面監聽中調用下面計算方法,可計算出VERTICAL豎着佈局的滑動距離spa

//找到即將移出屏幕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的寬度code

//找到即將移出屏幕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;複製代碼

2、計算Grid排列相同Itemcdn

豎着的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看一下,也是有註釋的

3、計算不一樣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…

寫完啦!


相關文章
相關標籤/搜索