Android獲取RecyclerView滑動(dòng)距離方法詳細(xì)講解
先說(shuō)能用的究極解決方案,大家著急的直接復(fù)制走,以后想了解再過(guò)來(lái)看
沒(méi)有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
}有一個(gè)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
}有多個(gè)header,其他Item一致
Integer[] headerHeightArray;
private int getScollYDistance(){
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getRecyclerView().getLayoutManager();
// 獲取第一個(gè)可見(jiàn)item的位置
int position = layoutManager.findFirstVisibleItemPosition();
// 獲取第一個(gè)可見(jiàn)item
View firstVisiableChildView = layoutManager.findViewByPosition(position);
// 必須考慮有沒(méi)有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();
}
}
// 獲取第一個(gè)可見(jiàn)item的高度
int itemHeight = firstVisiableChildView.getHeight();
// 獲取第一個(gè)可見(jiàn)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();
}
});試過(guò)的一些想法,都有一些問(wèn)題,有的可以彌補(bǔ),有的直接玩完
RecyclerView 雖然有g(shù)etScrollX() 和 getScrollY(), 但是測(cè)試發(fā)現(xiàn)這兩個(gè)函數(shù)總是返回0,太無(wú)語(yǔ)了。因此想到了下面幾種方法來(lái)實(shí)現(xiàn)獲取滑動(dòng)距離:
利用OnScrollListener
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
private int totalDy = ;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
totalDy -= dy;
}
});如代碼所述,totalDy的確保存了 RecyclerView 的滑動(dòng)距離,但是當(dāng)我向下滑動(dòng) RecyclerView ,之后插入/刪除/移動(dòng) Item 的時(shí)候,totalDy 就變得不精確了;比如刪除或者插入新的Item,那么totalDy就不能再回歸到 0了。這個(gè)可以通過(guò)當(dāng)刪除或者插入時(shí)來(lái)對(duì)totalDy進(jìn)行加減相應(yīng)的高度。
totalDy = recyclerView.computeVerticalScrollOffset();
然而compute方法計(jì)算出的并不是滑動(dòng)的精確距離,stackOverflow上有答案解釋其為 item 的平均高度 * 可見(jiàn) item 數(shù)目,不是我們需要的精確距離。
totalDy = recyclerView.getChildAt().getTop();
依靠第一個(gè)item的滑動(dòng)距離來(lái)進(jìn)行動(dòng)畫(huà)的設(shè)置,但是根據(jù)該方法得出的 totalDy 在滑動(dòng)到一定程度后清零。
這是因?yàn)閞ecyclerViewl.getChildAt(0) 返回的永遠(yuǎn)是第一個(gè)可見(jiàn)的child,不是所有view list 的第一個(gè)child,因此這種用法是得不到滑動(dòng)距離的。
另外下面這三種用法都是等價(jià)的,都是獲取第一個(gè)可見(jiàn)的child:
LinearLayoutManager layoutManager = (LinearLayoutManager) this.getLayoutManager();
View firstVisiableChildView = this.getChildAt();
View firstVisiableChildView = layoutManager.getChildAt()
int position = layoutManager.findFirstVisibleItemPosition();
View firstVisiableChildView = layoutManager.getChildAt(position)但是下面這種就不是獲取第一個(gè)可見(jiàn)的child,而是獲得所有view list 的第一個(gè)child。但是滑動(dòng)一段距離后它總是返回null,即第一個(gè)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滑動(dòng)距離方法詳細(xì)講解的文章就介紹到這了,更多相關(guān)Android獲取RecyclerView滑動(dòng)距離內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android使用Intent傳遞組件大數(shù)據(jù)
這篇文章主要介紹了Android使用Intent傳遞組件大數(shù)據(jù),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容詳情,感興趣的朋友可以參考一下2022-07-07
基于Flutter制作一個(gè)長(zhǎng)按展示操作項(xiàng)面板的桌面圖標(biāo)
Flutter是一種強(qiáng)大的跨平臺(tái)移動(dòng)應(yīng)用程序框架,它能夠幫助開(kāi)發(fā)者輕松地創(chuàng)建漂亮、快速、高效的應(yīng)用程序,本文的主題是如何在Flutter中制作一個(gè)長(zhǎng)按展示操作項(xiàng)面板的桌面圖標(biāo),在某些場(chǎng)景下,這個(gè)功能會(huì)讓?xiě)?yīng)用程序更加便利和易用2023-06-06
mui,h5+中實(shí)現(xiàn)控制頁(yè)面load顯示
這篇文章主要介紹了mui,h5+中實(shí)現(xiàn)控制頁(yè)面load顯示的相關(guān)代碼寫(xiě)法和運(yùn)用技巧,需要的朋友參考一下。2017-11-11
Android開(kāi)發(fā)中GridView用法示例
這篇文章主要介紹了Android開(kāi)發(fā)中GridView用法,簡(jiǎn)單說(shuō)明了GridView控件的功能并結(jié)合實(shí)例形式給出了GridView組合圖片顯示的具體功能實(shí)現(xiàn)方法與布局操作技巧,需要的朋友可以參考下2017-10-10
Android7.0版本影響開(kāi)發(fā)的改進(jìn)分析
這篇文章主要介紹了Android7.0版本影響開(kāi)發(fā)的改進(jìn),總結(jié)分析了Android7.0版本中比較常見(jiàn)的開(kāi)發(fā)注意事項(xiàng)與操作技巧,需要的朋友可以參考下2017-11-11
Android5.0中Material Design的新特性
這篇文章主要介紹了Android5.0中Material Design的新特性的相關(guān)資料,需要的朋友可以參考下2016-08-08
android PopupWindow點(diǎn)擊外部和返回鍵消失的解決方法
這篇文章主要介紹了android PopupWindow點(diǎn)擊外部和返回鍵消失的解決方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-02-02
android開(kāi)發(fā)教程之判斷是手機(jī)還是平板的方法
判斷是平板還是手機(jī),通過(guò)很多的方式都可以實(shí)現(xiàn),如:設(shè)備尺寸、DPI、版本號(hào)、是否具備電話(huà)功能等,不過(guò)有些沒(méi)有那么的精準(zhǔn),這里分享一個(gè)比較簡(jiǎn)潔的方法2014-04-04
Android7.0實(shí)現(xiàn)拍照和相冊(cè)選取圖片功能
這篇文章主要為大家詳細(xì)介紹了Android7.0實(shí)現(xiàn)拍照和相冊(cè)選取圖片功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
內(nèi)存泄露導(dǎo)致Android?中setVisibility()?失效原理
這篇文章主要介紹了內(nèi)存泄露導(dǎo)致Android?中setVisibility()?失效原理,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-07-07

