1. 程式人生 > >RecyclerView 計算滑動高度,這次比網上任何方法都靠譜

RecyclerView 計算滑動高度,這次比網上任何方法都靠譜

最近在做專案改版的時候,需要計算RV的滑動距離,RV的滑動距離谷歌爸爸並沒有直接回調給我們,不過網上倒是有很多方式,無外乎以下幾種。

轉載請註明出處 1.利用OnScrollListener,dy直接相加 純屬扯淡。一點都不靠譜 2.computeVerticalScrollOffset() 不靠譜。 stackOverflow上有答案解釋其為 item 的平均高度 * 可見 item 數目,不是我們需要的精確距離。 而且我們在OnScrollListener中去取該值,一直為0,不符合預期。 3. recyclerView.getChildAt(0).getTop(); 不靠譜 原因recyclerView.getChildAt(0)得到的永遠是介面可見的第一個View,取值必然不對。 layoutManager.findViewByPosition(0)這種方式當第一個View被Recycle後會返回null。 4.網上貌似挺推崇這個方式的

我的意見,不靠譜,不推薦,因為計算複雜,一個RV裡不可能只有一種item,每個item高度不同,這種方式缺陷就是必須高度相同。如果不同,需要單獨計算item高度,複雜,況且萬一RV有間隔呢,間隔不同呢?所以這個方式不靠

public int getScollYDistance() {  
    LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();  
    int position = layoutManager.findFirstVisibleItemPosition();  
    View firstVisiableChildView = layoutManager.findViewByPosition(position);  
    int
itemHeight = firstVisiableChildView.getHeight(); return (position) * itemHeight - firstVisiableChildView.getTop(); }

所以終極殺招是什麼呢?

new 一個空View,在RV的OnScrollListener將dy傳入空View的scrollBy方法中,然後呼叫該View的getScrollY方法即可! 示例程式碼如下

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            emptyView.scrollBy(0,dy);
            Log.d(TAG, "onScrolled: "+(emptyView.getScrollY()));


          }
        }
    });

這個方法與item高度無關,與介面的呈現方式均無關。可能有人不信,我們測試一下,測試程式碼如下:

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                emptyView.scrollBy(0,dy);
                Log.d(TAG, "onScrolled: "+(emptyView.getScrollY()));
                if (lm.findFirstVisibleItemPosition()==1){
                    Log.d(TAG, "onCreate: "+getItemHeight(recyclerView));
                    nullView.getHeight();
                }
            }

意思就是,測量第一個View的高度,與我們滾動距離比較是否一致,為減小誤差,我們當第一個不可見時候報錯,nullView會報空指標,直接退出程式

測試效果如下 itemHeight 750; scrollY 751; 這裡寫圖片描述 可見誤差很小。

那麼,當item高度不一致的時候呢?當RV有padding/margin的時候呢? 當每個item之間有間隔(itemdecration)的時候測量結果還準確嗎?

準確的,誤差很小,測試結果就不貼了,可自行測試。

該方法屬於View的的方法,無需考慮每個item的高度問題,也不用管介面上有多少種view,簡單粗暴就能算出view的滾動高度,簡直妙哉!