簡述
在Android 開發(fā)中夕膀,RecyclerView 是我們開發(fā)者最為常用的控件栓袖,用于展示大量的數(shù)據(jù),為此其相關(guān)的item滾動知識尤為重要店诗,此篇文章不講解原理裹刮,而是提供相關(guān)函數(shù),給需要的小伙伴們提供思路庞瘸,其內(nèi)部原理有興趣的可以去閱讀源碼捧弃。
RecyclerView 的幾個常見滾動方法
- scrollToPosition(int position)
該方法是滾動到指定item,是瞬間就移動到我們設(shè)置position,若超過適配器的item數(shù)目(假設(shè)只有20個item,卻指定滾動到第30個)违霞,是沒有效果嘴办。若該item 已經(jīng)存在于屏幕內(nèi),同樣調(diào)用該函數(shù)也是沒有效果的买鸽。
效果圖如下:
- moothScrollToPosition(int position)
滾動到指定item, 同時帶有滑動一段距離的效果涧郊,該方法與 scrollToPosition相比不會顯得突兀生硬,但是遇到該item已經(jīng)存在于屏幕內(nèi)的情況眼五,同樣是無效的妆艘。
效果圖如下:
- scrollBy(int x, int y)
這個方法是是去控制我們移動的增量,第一個參數(shù)指x軸方向的看幼,第二參數(shù)是y軸方向批旺,設(shè)置個scrollBy(0,200) ,表示往y軸上移動200像素的距離诵姜。
效果圖如下:
-
scrollTo(int x, int y)
關(guān)于這個方法汽煮,點(diǎn)擊跳進(jìn)去看,發(fā)現(xiàn)那里只有打了個日志棚唆,提示我們RecyclerView不支持滾動到絕對位置暇赤,讓我們用scrollToPosition方法代替,故設(shè)置什么數(shù)值都是無用宵凌。
源碼截圖如下
進(jìn)階使用 (scrollToPositionWithOffset)
講完四個滾動的函數(shù)翎卓,發(fā)現(xiàn)好像還是不能夠解決常用的問題,這里我列出我遇到的問題摆寄,并且提供解決代碼思路。
- 問題一
在設(shè)置了垂直的布局管理器的前提下坯门,不管該item是否在屏幕內(nèi)微饥,需要滾動的指定item必須位于屏幕第一個位置。(常見的需求場景:1.排名榜上古戴,需要快速定位滾動到用戶的相關(guān)名次欠橘。2.點(diǎn)擊滾動返回頂部。3.字母索引定位现恼,如微信聯(lián)系人的字母索引)
解決方案:獲取ry(開發(fā)者用到的RecyclerView)的LinearLayoutManager 對象肃续,使用其scrollToPositionWithOffset(int position, int offset)函數(shù), 其中第一個參數(shù)是指滾動到指定的適配器位置叉袍, 第二個參數(shù)則是給定的偏移量
按鈕點(diǎn)擊事件代碼如下:
btn_jump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((LinearLayoutManager)ry.getLayoutManager()).scrollToPositionWithOffset(30,0);
}
});
效果圖如下:
- 問題二
當(dāng)用戶滑動到指定位置后始锚,若更新整個列表數(shù)據(jù)的時候,會重新從第一個開始(需求場景:當(dāng)列表顯示的是一堆股票與其相關(guān)的漲幅率喳逛,股票需要每隔5秒刷新數(shù)據(jù)瞧捌,同時不得重置用戶的的滾動位置)
解決方案:監(jiān)聽ry的滾動狀態(tài),獲取用戶滑動后的記錄位置,在刷新數(shù)據(jù)后姐呐,ry再滾動到指定的位置殿怜,這個方法也需要使用到scrollToPositionWithOffset(int position, int offset)函數(shù)
代碼如下:
ry的滾動監(jiān)聽
ry.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
getPositionAndOffset(ry);
}
});
getPositionAndOffset(ry) 是記錄位置與獲取偏移量
/**
* 記錄RecyclerView當(dāng)前位置
* lastOffset 最新的偏移量
* lastPosition 最新的滑動item的索引位置
*/
private int lastOffset=0,lastPosition=0;
private void getPositionAndOffset(RecyclerView mRecyclerView) {
LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
//獲取可視的第一個view
View topView = layoutManager.getChildAt(0);
if(topView != null) {
//獲取與該view的頂部的偏移量
lastOffset = topView.getTop();
//得到該View的數(shù)組位置
lastPosition = layoutManager.getPosition(topView);
}
}
在數(shù)據(jù)刷新后,設(shè)置到adapter適配器后曙砂,調(diào)用scrollToPositionWithOffset方法
/**
* 讓RecyclerView滾動到指定位置
*/
private void scrollToPosition() {
if(ry.getLayoutManager() != null && lastPosition >= 0) {
((LinearLayoutManager) ry.getLayoutManager()).scrollToPositionWithOffset(lastPosition, lastOffset);
}
}
效果圖如下:
至此头谜,相關(guān)知識已經(jīng)講解完畢,錯誤之處希望各位大佬指出鸠澈,大家一起進(jìn)步柱告,若是能給各位一點(diǎn)啟發(fā),也不枉費(fèi)寫了這篇文章款侵。