RecyclerView滑動(dòng)到指定Position的方法
Question
最近在寫 SideBar 的時(shí)候遇到一個(gè)問(wèn)題,當(dāng)執(zhí)行 Recyclerview 的 smoothScrollToPosition(position) 的時(shí)候,Recyclerview 看上去并沒(méi)有滾動(dòng)到指定位置。
Analysis
當(dāng)然,這并不是方法的bug,而是 smoothScrollToPosition(position) 的執(zhí)行效果有三種情況,需要區(qū)分。
·目標(biāo)position在第一個(gè)可見(jiàn)項(xiàng)之前 。
這種情況調(diào)用smoothScrollToPosition能夠平滑的滾動(dòng)到指定位置,并且置頂。
·目標(biāo)position在第一個(gè)可見(jiàn)項(xiàng)之后,最后一個(gè)可見(jiàn)項(xiàng)之前。
這種情況下,調(diào)用smoothScrollToPosition不會(huì)有任何效果···
·目標(biāo)position在最后一個(gè)可見(jiàn)項(xiàng)之后。
這種情況調(diào)用smoothScrollToPosition會(huì)把目標(biāo)項(xiàng)滑動(dòng)到屏幕最下方···
Solution
鑒于這三種情況,我想大多數(shù)情況下都無(wú)法滿足我們的滑動(dòng)要求。為了實(shí)現(xiàn) Recyclerview 把指定 item 滑動(dòng)到屏幕頂端的需求,我們需要對(duì)上面三種情況分別處理。
/** 目標(biāo)項(xiàng)是否在最后一個(gè)可見(jiàn)項(xiàng)之后*/ private boolean mShouldScroll; /** 記錄目標(biāo)項(xiàng)位置*/ private int mToPosition; /** * 滑動(dòng)到指定位置 * @param mRecyclerView * @param position */ private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) { // 第一個(gè)可見(jiàn)位置 int firstItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(0)); // 最后一個(gè)可見(jiàn)位置 int lastItem = mRecyclerView.getChildLayoutPosition(mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1)); if (position < firstItem) { // 如果跳轉(zhuǎn)位置在第一個(gè)可見(jiàn)位置之前,就smoothScrollToPosition可以直接跳轉(zhuǎn) mRecyclerView.smoothScrollToPosition(position); } else if (position <= lastItem) { // 跳轉(zhuǎn)位置在第一個(gè)可見(jiàn)項(xiàng)之后,最后一個(gè)可見(jiàn)項(xiàng)之前 // smoothScrollToPosition根本不會(huì)動(dòng),此時(shí)調(diào)用smoothScrollBy來(lái)滑動(dòng)到指定位置 int movePosition = position - firstItem; if (movePosition >= 0 && movePosition < mRecyclerView.getChildCount()) { int top = mRecyclerView.getChildAt(movePosition).getTop(); mRecyclerView.smoothScrollBy(0, top); } }else { // 如果要跳轉(zhuǎn)的位置在最后可見(jiàn)項(xiàng)之后,則先調(diào)用smoothScrollToPosition將要跳轉(zhuǎn)的位置滾動(dòng)到可見(jiàn)位置 // 再通過(guò)onScrollStateChanged控制再次調(diào)用smoothMoveToPosition,執(zhí)行上一個(gè)判斷中的方法 mRecyclerView.smoothScrollToPosition(position); mToPosition = position; mShouldScroll = true; } }
再通過(guò)onScrollStateChanged控制再次調(diào)用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); } } }); }
目前這個(gè)解決方法有兩個(gè)已知的問(wèn)題
1、當(dāng)目標(biāo)項(xiàng)在最后一個(gè)可見(jiàn)項(xiàng)之后的時(shí)候,由于我們先執(zhí)行smoothScrollToPosition方法,然后在OnScrollListener中執(zhí)行smoothMoveToPosition方法,在滑動(dòng)的時(shí)候不夠連貫。
2、在手動(dòng)滑動(dòng)的時(shí)候執(zhí)行該方法,會(huì)有極小的概率滑動(dòng)的位置出現(xiàn)偏差。
如果你有更好解決辦法,希望不吝指教。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- RecyclerView+CardView實(shí)現(xiàn)橫向卡片式滑動(dòng)效果
- Android中RecyclerView實(shí)現(xiàn)橫向滑動(dòng)代碼
- Android中RecyclerView嵌套滑動(dòng)沖突解決的代碼片段
- Android中RecyclerView 滑動(dòng)時(shí)圖片加載的優(yōu)化
- android RecyclerView側(cè)滑菜單,滑動(dòng)刪除,長(zhǎng)按拖拽,下拉刷新上拉加載
- Android實(shí)現(xiàn)評(píng)論欄隨Recyclerview滑動(dòng)左右移動(dòng)
- Android 滑動(dòng)監(jiān)聽(tīng)RecyclerView線性流+左右劃刪除+上下移動(dòng)
- Android開(kāi)發(fā)中RecyclerView模仿探探左右滑動(dòng)布局功能
- Android RecyclerView滑動(dòng)刪除和拖動(dòng)排序
- Android嵌套R(shí)ecyclerView左右滑動(dòng)替代自定義view
- RecyclerView實(shí)現(xiàn)探探卡片滑動(dòng)效果
相關(guān)文章
Android實(shí)現(xiàn)仿網(wǎng)易新聞的頂部導(dǎo)航指示器
這篇文章主要介紹了Android實(shí)現(xiàn)仿網(wǎng)易新聞的頂部導(dǎo)航指示器的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08基于Android開(kāi)發(fā)支持表情的實(shí)現(xiàn)詳解
本篇文章是對(duì)在Android開(kāi)發(fā)中支持表情的實(shí)現(xiàn)代碼進(jìn)行了介紹。需要的朋友參考下2013-05-05如何通過(guò)Battery Historian分析Android APP耗電情況
Android 從兩個(gè)層面統(tǒng)計(jì)電量的消耗,分別為軟件排行榜及硬件排行榜。它們各有自己的耗電榜單,軟件排行榜為機(jī)器中每個(gè) App 的耗電榜單,硬件排行榜則為各個(gè)硬件的耗電榜單。這兩個(gè)排行榜的統(tǒng)計(jì)是互為獨(dú)立,互不干擾的2021-06-06基于Android自定義控件實(shí)現(xiàn)刮刮樂(lè)效果
這篇文章主要介紹了基于Android自定義控件實(shí)現(xiàn)刮刮樂(lè)效果 的相關(guān)資料,需要的朋友可以參考下2015-12-12Android自定義實(shí)現(xiàn)開(kāi)關(guān)按鈕代碼
經(jīng)常可以看到一些選擇開(kāi)個(gè)狀態(tài)的配置文件,但是外觀都不多好看。我感覺(jué)還是自定義的比較好,下面小編給大家介紹通過(guò)Android自定義實(shí)現(xiàn)開(kāi)關(guān)按鈕代碼,感興趣的童鞋一起學(xué)習(xí)吧2016-05-05解決Android studio用真機(jī)調(diào)試時(shí)logcat一直輸出日志問(wèn)題
這篇文章主要介紹了解決Android studio用真機(jī)調(diào)試時(shí)logcat一直輸出日志問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04Android實(shí)現(xiàn)倒計(jì)時(shí)結(jié)束后跳轉(zhuǎn)頁(yè)面功能
最近在工作中遇到一個(gè)需求,需要在倒計(jì)時(shí)一段時(shí)間后進(jìn)行跳轉(zhuǎn)頁(yè)面,通過(guò)查找相關(guān)資料發(fā)現(xiàn)其中涉及的知識(shí)還不少,所以分享出來(lái),下面這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)倒計(jì)時(shí)結(jié)束后跳轉(zhuǎn)頁(yè)面功能的相關(guān)資料,需要的朋友可以參考下。2017-11-11Android 讓自定義TextView的drawableLeft與文本一起居中
本文主要介紹Android 自定義控件TextView顯示居中問(wèn)題,在開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)遇到控件的重寫,這里主要介紹TextView的drawableLeft與文本一起居中的問(wèn)題2016-07-07Android系統(tǒng)對(duì)話框使用詳解(最詳細(xì))
這篇文章主要介紹了Android系統(tǒng)對(duì)話框使用詳解(最詳細(xì)),需要的朋友可以參考下2017-10-10RecyclerView+SnapHelper實(shí)現(xiàn)無(wú)限循環(huán)篩選控件
這篇文章主要為大家詳細(xì)介紹了RecyclerView+SnapHelper實(shí)現(xiàn)無(wú)限循環(huán)篩選控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10