欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android獲取RecyclerView滑動距離方法詳細講解

 更新時間:2023年01月13日 09:02:07   作者:AllenC6  
RecyclerView是Android一個更強大的控件,其不僅可以實現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實現(xiàn)數(shù)據(jù)縱向滾動,也可以實現(xiàn)橫向滾動(ListView做不到橫向滾動)。接下來講解RecyclerView的用法

先說能用的究極解決方案,大家著急的直接復(fù)制走,以后想了解再過來看

沒有header,且所有Item的高度一致

    private fun getScrollYDistance(recyclerView: RecyclerView): Int? {
        kotlin.runCatching {
            val layoutManager = recyclerView.layoutManager as LinearLayoutManager
            val position = layoutManager.findFirstVisibleItemPosition()
            val firstVisibleChildView = layoutManager.findViewByPosition(position)
            val itemHeight = firstVisibleChildView!!.height
            return position * itemHeight - firstVisibleChildView.top
        }
        return null
    }

有一個header,其他所有Item高度一致

    var headerHeight = 0
    private fun getScrollYDistance(recyclerView: RecyclerView): Int? {
        kotlin.runCatching {
            val layoutManager = recyclerView.layoutManager as LinearLayoutManager
            val position = layoutManager.findFirstVisibleItemPosition()
            if (position == 0) {
                val headerView = layoutManager.findViewByPosition(0)
                headerHeight = headerView!!.height
            }
            val firstVisibleChildView = layoutManager.findViewByPosition(position)
            val itemHeight = firstVisibleChildView!!.height
            return if (position == 0) {
                position * itemHeight - firstVisibleChildView.top
            } else {
                (position - 1) * itemHeight - firstVisibleChildView.top + headerHeight
            }
        }
        return null
    }

有多個header,其他Item一致

   Integer[] headerHeightArray;
    private int getScollYDistance(){
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getRecyclerView().getLayoutManager();
        // 獲取第一個可見item的位置
        int position = layoutManager.findFirstVisibleItemPosition();
        // 獲取第一個可見item
        View firstVisiableChildView = layoutManager.findViewByPosition(position);
        // 必須考慮有沒有Header  預(yù)存下所有header的高度
        int headerCount = adapter.getHeaderCount();
        if (headerCount > 0) {
            if (headerHeightArray == null) {
                headerHeightArray = new Integer[headerCount];
            }
            if (position < headerCount) {
                View headerView_i = layoutManager.findViewByPosition(position);
                headerHeightArray[position] = headerView_i.getHeight();
            }
        }
        // 獲取第一個可見item的高度
        int itemHeight = firstVisiableChildView.getHeight();
        // 獲取第一個可見item的位置
        int distance = 0;
        if (position == 0) {
            distance = position * itemHeight - firstVisiableChildView.getTop();
        } else {
            int allHeaderHeight = 0;
            for (int i = 0; i < Math.min(position,headerCount); i++) {
                allHeaderHeight = allHeaderHeight + headerHeightArray[i];
            }
            distance = (position - Math.min(position,headerCount)) * itemHeight - firstVisiableChildView.getTop() + allHeaderHeight;
        }
        return distance;
    }

注意調(diào)用位置:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    getScollYDistance();
                }
            });

試過的一些想法,都有一些問題,有的可以彌補,有的直接玩完

RecyclerView 雖然有g(shù)etScrollX() 和 getScrollY(), 但是測試發(fā)現(xiàn)這兩個函數(shù)總是返回0,太無語了。因此想到了下面幾種方法來實現(xiàn)獲取滑動距離:

利用OnScrollListener

        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            private int totalDy = ;
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                totalDy -= dy;
            }
        });

如代碼所述,totalDy的確保存了 RecyclerView 的滑動距離,但是當我向下滑動 RecyclerView ,之后插入/刪除/移動 Item 的時候,totalDy 就變得不精確了;比如刪除或者插入新的Item,那么totalDy就不能再回歸到 0了。這個可以通過當刪除或者插入時來對totalDy進行加減相應(yīng)的高度。

totalDy = recyclerView.computeVerticalScrollOffset();

然而compute方法計算出的并不是滑動的精確距離,stackOverflow上有答案解釋其為 item 的平均高度 * 可見 item 數(shù)目,不是我們需要的精確距離。

totalDy = recyclerView.getChildAt().getTop();

依靠第一個item的滑動距離來進行動畫的設(shè)置,但是根據(jù)該方法得出的 totalDy 在滑動到一定程度后清零。

這是因為recyclerViewl.getChildAt(0) 返回的永遠是第一個可見的child,不是所有view list 的第一個child,因此這種用法是得不到滑動距離的。

另外下面這三種用法都是等價的,都是獲取第一個可見的child:

       LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
       View firstVisiableChildView = this.getChildAt();
       View firstVisiableChildView = layoutManager.getChildAt()
       int position = layoutManager.findFirstVisibleItemPosition();
       View firstVisiableChildView = layoutManager.getChildAt(position)

但是下面這種就不是獲取第一個可見的child,而是獲得所有view list 的第一個child。但是滑動一段距離后它總是返回null,即第一個child被recycle后,總是返回null。

//Don't use this function to get the first item, it will return null when the first item is recycled.
LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
View child2 = layoutManager.findViewByPosition();

到此這篇關(guān)于Android獲取RecyclerView滑動距離方法詳細講解的文章就介紹到這了,更多相關(guān)Android獲取RecyclerView滑動距離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論