Android獲取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)文章
Android使用Intent傳遞組件大數(shù)據(jù)
這篇文章主要介紹了Android使用Intent傳遞組件大數(shù)據(jù),文章圍繞主題展開詳細的內(nèi)容詳情,感興趣的朋友可以參考一下2022-07-07Android5.0中Material Design的新特性
這篇文章主要介紹了Android5.0中Material Design的新特性的相關(guān)資料,需要的朋友可以參考下2016-08-08android PopupWindow點擊外部和返回鍵消失的解決方法
這篇文章主要介紹了android PopupWindow點擊外部和返回鍵消失的解決方法,非常具有實用價值,需要的朋友可以參考下。2017-02-02內(nèi)存泄露導(dǎo)致Android?中setVisibility()?失效原理
這篇文章主要介紹了內(nèi)存泄露導(dǎo)致Android?中setVisibility()?失效原理,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-07-07