Android RecyclerView 滾動的技巧知識

簡述

在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ù)也是沒有效果的买鸽。
    效果圖如下:
錄制效果圖1.gif
  • moothScrollToPosition(int position)
    滾動到指定item, 同時帶有滑動一段距離的效果涧郊,該方法與 scrollToPosition相比不會顯得突兀生硬,但是遇到該item已經(jīng)存在于屏幕內(nèi)的情況眼五,同樣是無效的妆艘。
    效果圖如下:
錄制效果圖2.gif
  • scrollBy(int x, int y)
    這個方法是是去控制我們移動的增量,第一個參數(shù)指x軸方向的看幼,第二參數(shù)是y軸方向批旺,設(shè)置個scrollBy(0,200) ,表示往y軸上移動200像素的距離诵姜。
    效果圖如下:
錄制效果圖3.gif
  • scrollTo(int x, int y)
    關(guān)于這個方法汽煮,點(diǎn)擊跳進(jìn)去看,發(fā)現(xiàn)那里只有打了個日志棚唆,提示我們RecyclerView不支持滾動到絕對位置暇赤,讓我們用scrollToPosition方法代替,故設(shè)置什么數(shù)值都是無用宵凌。
    源碼截圖如下


    scrollTo 源碼 .png
進(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);
            }
        });

效果圖如下:

錄制效果圖4.gif
  • 問題二
    當(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);
        }
    }

效果圖如下:

錄制效果圖5.gif

至此头谜,相關(guān)知識已經(jīng)講解完畢,錯誤之處希望各位大佬指出鸠澈,大家一起進(jìn)步柱告,若是能給各位一點(diǎn)啟發(fā),也不枉費(fèi)寫了這篇文章款侵。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末末荐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子新锈,更是在濱河造成了極大的恐慌甲脏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妹笆,死亡現(xiàn)場離奇詭異块请,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)拳缠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門墩新,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人窟坐,你說我怎么就攤上這事海渊。” “怎么了哲鸳?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵臣疑,是天一觀的道長。 經(jīng)常有香客問我徙菠,道長讯沈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任婿奔,我火速辦了婚禮缺狠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萍摊。我一直安慰自己挤茄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布冰木。 她就那樣靜靜地躺著驮樊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囚衔,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天挖腰,我揣著相機(jī)與錄音,去河邊找鬼练湿。 笑死猴仑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肥哎。 我是一名探鬼主播辽俗,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼篡诽!你這毒婦竟也來了崖飘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤杈女,失蹤者是張志新(化名)和其女友劉穎朱浴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體达椰,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翰蠢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了啰劲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梁沧。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蝇裤,靈堂內(nèi)的尸體忽然破棺而出廷支,到底是詐尸還是另有隱情,我是刑警寧澤栓辜,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布恋拍,位于F島的核電站,受9級特大地震影響啃憎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜似炎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一辛萍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羡藐,春花似錦贩毕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春谆甜,著一層夾襖步出監(jiān)牢的瞬間垃僚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工规辱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谆棺,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓罕袋,卻偏偏與公主長得像改淑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子浴讯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345