RecyclerView滑動到指定Position的方法
Question
最近在寫 SideBar 的時候遇到一個問題,當執行 Recyclerview 的 smoothScrollToPosition(position)
的時候,Recyclerview 看上去並沒有滾動到指定位置。
Analysis
當然,這並不是方法的bug,而是 smoothScrollToPosition(position)
的執行效果有三種情況,需要區分。
-
目標position在第一個可見項之前 。
這種情況呼叫smoothScrollToPosition
能夠平滑的滾動到指定位置,並且置頂。 -
目標position在第一個可見項之後,最後一個可見項之前。
這種情況下,呼叫smoothScrollToPosition
不會有任何效果··· -
目標position在最後一個可見項之後。
這種情況呼叫smoothScrollToPosition
會把目標項滑動到螢幕最下方···
Solution
鑑於這三種情況,我想大多數情況下都無法滿足我們的滑動要求。為了實現 Recyclerview 把指定 item 滑動到螢幕頂端的需求,我們需要對上面三種情況分別處理。
/** 目標項是否在最後一個可見項之後*/
private boolean mShouldScroll;
/** 記錄目標項位置*/
private int mToPosition;
/**
* 滑動到指定位置
* @param mRecyclerView
* @param position
*/
private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) {
// 第一個可見位置
int firstItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0));
// 最後一個可見位置
int lastItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1));
if (position < firstItem) {
// 如果跳轉位置在第一個可見位置之前,就smoothScrollToPosition可以直接跳轉
mRecyclerView.smoothScrollToPosition(position);
} else if (position <= lastItem) {
// 跳轉位置在第一個可見項之後,最後一個可見項之前
// smoothScrollToPosition根本不會動,此時呼叫smoothScrollBy來滑動到指定位置
int movePosition = position - firstItem;
if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) {
int top = mRecyclerView.getChildAt(movePosition).getTop();
mRecyclerView.smoothScrollBy(0, top);
}
}else {
// 如果要跳轉的位置在最後可見項之後,則先呼叫smoothScrollToPosition將要跳轉的位置滾動到可見位置
// 再通過onScrollStateChanged控制再次呼叫smoothMoveToPosition,執行上一個判斷中的方法
mRecyclerView.smoothScrollToPosition(position);
mToPosition = position;
mShouldScroll = true;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
再通過onScrollStateChanged控制再次呼叫smoothMoveToPosition
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (mShouldScroll){
mShouldScroll = false;
smoothMoveToPosition(mRecyclerView,mToPosition);
}
}
});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
目前這個解決方法有兩個已知的問題
- 當目標項在最後一個可見項之後的時候,由於我們先執行
smoothScrollToPosition
方法,然後在OnScrollListener
中執行smoothMoveToPosition
方法,在滑動的時候不夠連貫。 - 在手動滑動的時候執行該方法,會有極小的概率滑動的位置出現偏差。
如果你有更好解決辦法,希望不吝指教。
相關文章
- Android開發:RecyclerView平滑流暢的滑動到指定位置AndroidView
- RecyclerView 、ViewPager 左右滑動衝突Viewpager
- RecyclerView滑動距離計算View
- recyclerview 彈性滑動 + 中間元素放大View
- sqlloader指定positionSQL
- RecyclerView 實現滑動刪除和拖拽功能View
- RecyclerView實現滑動刪除和拖拽功能View
- Tips-移動端滑動固頂效果(position: sticky)
- RecyclerView 滑動之後顯示資料錯亂View
- DiffUtils讓你的RecyclerView如斯順滑View
- (有圖)仿QQ側滑選單:RecyclerView側滑選單,長按拖拽,滑動刪除View
- 解決ScrollView巢狀RecyclerView滑動卡頓問題View巢狀
- NestedScrollView+RecyclerView 滑動卡頓簡單解決方案View
- RecyclerView平滑到指定位置View
- 基於滑動場景解析RecyclerView的回收複用機制原理View
- ScrollView巢狀RecyclerView滑動衝突相關問題View巢狀
- 解決 ScrollView 巢狀 RecyclerView 時,慣性滑動失效的問題View巢狀
- RecyclerView滑動到底部的時候點選按鈕直接返回頂部View
- RecyclerView與下拉重新整理控制元件滑動衝突的解決View控制元件
- jQuery position()方法jQuery
- NestedScrollView巢狀RecyclerView時滑動不流暢問題的解決辦法View巢狀
- 點選圖片大圖預覽,RecyclerView + PhotoView 滑動衝突,RecyclerView不回撥SCROLL_STATE_IDLEView
- 自定義RecyclerView實現側滑刪除View
- 不要在 XML 設定,解決 NestedScrollView 巢狀 RecyclerView 滑動卡頓XMLView巢狀
- RecyclerView 梳理:點選&長按事件、分割線、拖曳排序、滑動刪除View事件排序
- 滾動到指定位置jsJS
- 平滑的滾動listview到一個指定位View
- 解壓 TAR 檔案到指定目錄的方法
- YogaKit中 position 的使用方法
- ScrollView(RecyclerView等)為什麼會自動滾動原理分析,還有阻止自動滑動的解決方View
- ScrollView(RecyclerView等)為什麼會自動滾動原理分析,還有阻止自動滑動的解決方案View
- scrollview滾動到指定位置View
- 自定義RecyclerView新增HeaderView,新增FooterView,實現滑動到底部,載入更多ViewHeader
- TV RecyclerView 滑動後操作保持落焦在左側第一個ViewView
- Android ScrollView滾動到指定View的位置AndroidView
- Linux解壓檔案到指定目錄的方法Linux
- RecyclerView的滾動事件研究View事件
- web前端仿手機左右滑動(手滑+自動滑動)Web前端