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.網上貌似挺推崇這個方式的
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的滾動高度,簡直妙哉!