Android獲取RecyclerView滑動距離方法詳細講解
先說能用的究極解決方案,大家著急的直接復制走,以后想了解再過來看
沒有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 預存下所有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;
}注意調用位置:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
getScollYDistance();
}
});試過的一些想法,都有一些問題,有的可以彌補,有的直接玩完
RecyclerView 雖然有getScrollX() 和 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進行加減相應的高度。
totalDy = recyclerView.computeVerticalScrollOffset();
然而compute方法計算出的并不是滑動的精確距離,stackOverflow上有答案解釋其為 item 的平均高度 * 可見 item 數(shù)目,不是我們需要的精確距離。
totalDy = recyclerView.getChildAt().getTop();
依靠第一個item的滑動距離來進行動畫的設置,但是根據(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();
到此這篇關于Android獲取RecyclerView滑動距離方法詳細講解的文章就介紹到這了,更多相關Android獲取RecyclerView滑動距離內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android使用Intent傳遞組件大數(shù)據(jù)
這篇文章主要介紹了Android使用Intent傳遞組件大數(shù)據(jù),文章圍繞主題展開詳細的內容詳情,感興趣的朋友可以參考一下2022-07-07
Android5.0中Material Design的新特性
這篇文章主要介紹了Android5.0中Material Design的新特性的相關資料,需要的朋友可以參考下2016-08-08
android PopupWindow點擊外部和返回鍵消失的解決方法
這篇文章主要介紹了android PopupWindow點擊外部和返回鍵消失的解決方法,非常具有實用價值,需要的朋友可以參考下。2017-02-02
內存泄露導致Android?中setVisibility()?失效原理
這篇文章主要介紹了內存泄露導致Android?中setVisibility()?失效原理,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-07-07

