RecyclerView使用技巧-自動(dòng)滾動(dòng)

今天跟大家分享下RecyclerView怎么使它的條目自動(dòng)滾動(dòng)


其實(shí)做這個(gè)也是項(xiàng)目中有個(gè)需求需要用到,但是在網(wǎng)上找遍了也沒有找到專門講解這個(gè)知識(shí)點(diǎn)的文章。
所以這段時(shí)間自己研究懂了后 分享給大家。

再次更新下驻右,找到了一個(gè)新的解決辦法迁客,那就是 RecyclerView 的smoothScrollToPosition方法。其實(shí)這個(gè)方法之前用過重虑,也是可以平滑滾動(dòng),但是速度太快秦士,沒辦法自定義時(shí)間缺厉。所以就沒有說 ,但是昨天晚上經(jīng)過簡(jiǎn)友的提醒隧土,我又細(xì)心的找了一遍提针,發(fā)現(xiàn)這個(gè)方法確實(shí)是可以改變時(shí)間的 而且不用像下面那么麻煩而且解決了所有問題,簡(jiǎn)直棒到?jīng)]朋友曹傀,那么下面是解決方法辐脖。
[RecyclerView調(diào)用smoothScrollToPosition() 控制滑動(dòng)速度]


一想到條目自動(dòng)滾動(dòng),讓我想起了ListView有一個(gè)方法叫做setSelection(int position) 可以設(shè)置一個(gè)位置 然后他就會(huì)自動(dòng)滾動(dòng)到指定的位置皆愉,但是現(xiàn)在這都什么年代了 果斷拋棄了LisView 使用RecyclerView來做 至于RecyclerView有什么好處 為什么使用它 大家自行Google吧嗜价。

那么我們回到RecyclerView中想想該怎么實(shí)現(xiàn)這個(gè)呢 找了找RecyclerView中方法 發(fā)現(xiàn)有這么一個(gè)方法scrollToPosition(int position)這個(gè)方法跟ListView的一樣也是傳入進(jìn)去一位置 自動(dòng)給你跳到指定的位置 艇抠,這會(huì)兒 你可能心想 我去這不是直接就實(shí)現(xiàn)了么,但是 你用下看效果 那個(gè)條目跟瞬移是的 直接就干到最底部了炭剪! (如果你們產(chǎn)品能接受 那就當(dāng)我沒說) 既然這樣不行 那就換练链,突然想到谷歌給我們提供了一個(gè)叫做Scroller的類 看描述!

Scroller是一個(gè)專門用于處理滾動(dòng)效果的工具類奴拦,可能在大多數(shù)情況下媒鼓,我們直接使用Scroller的場(chǎng)景并不多,但是很多大家所熟知的控件在內(nèi)部都是使用Scroller來實(shí)現(xiàn)的错妖,如ViewPager绿鸣、ListView等。

不熟悉的可以看下這篇博客[Android Scroller完全解析暂氯,關(guān)于Scroller你所需知道的一切]


其實(shí)說到底他也就還是個(gè)工具類 也就是說其實(shí)最后能讓Item滾動(dòng)并不是他 這時(shí)候就要介紹下我們的另外兩個(gè)方法 scrollTo()和scrollBy()這兩個(gè)方法 這兩個(gè)才是主角 就是這個(gè)兩個(gè)方法才能讓我們的View滑動(dòng) 他們的使用也很簡(jiǎn)單 就是傳入 一個(gè)x坐標(biāo) 和一個(gè) y坐標(biāo) 他就會(huì)照著你給的位置去移動(dòng) 他倆不一樣的地方無非就是 scrollTo 是以當(dāng)前View的初始位置開始移動(dòng) 而scrollBy是根據(jù)當(dāng)前位置來進(jìn)行移動(dòng) 而其他的特性大家也可以看上面的博客 這里就不絮叨了潮模,

那么大家知道scrollTo()和scrollBy()的移動(dòng)方式 就是移動(dòng)他的內(nèi)容 而不是他自己本身,那這里正好 我們不就是想移動(dòng)RecyclerView的Item么?但是用過你會(huì)發(fā)現(xiàn)痴施,我去擎厢,這家伙怎么跟之前用的那個(gè)設(shè)置位置移動(dòng)的方法一個(gè)德行 ,也嗖的一下就干過去了 .不過他并不是移動(dòng)到底 如果是上下滑動(dòng)的話 是根據(jù)你的y值而決定的 。

那么下面就要用到Scroller這個(gè)類了
使用startScroll(int startX, int startY, int dx, int dy)開始啟動(dòng)滑動(dòng) 并且重寫computeScroll()方法完成值得過度 并且調(diào)用invalidate();方法請(qǐng)求View數(shù)重新繪制 這個(gè)一定要記得調(diào)用 不要會(huì)沒有效果

@Override public void computeScroll() { //重寫computeScroll()方法辣吃,并在其內(nèi)部完成平滑滾動(dòng)的邏輯 if (mScroller.computeScrollOffset()) { scrollBy(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } }
看下效果

GIF.gif

使用后你會(huì)發(fā)現(xiàn)动遭,哎確實(shí)是自動(dòng)滾動(dòng)了,而且也不是嗖的一下在就沒了神得。 好像這樣確實(shí)是已經(jīng)實(shí)現(xiàn)了厘惦,但是如果我想讓他滾動(dòng)的在慢一點(diǎn)怎么辦?或者說我想他的滾動(dòng)速度是可以調(diào)的哩簿,那怎么辦 宵蕉? 其實(shí)這個(gè)startScroll 還有一個(gè)重載的方法 startScroll(int startX, int startY, int dx, int dy, int duration) 可以再添加一個(gè)時(shí)間,單位是毫秒节榜。

但是這里還有一個(gè)問題就是RecyclerView是不讓使用scrollTo方法 如果使用了是沒有效果的 而且還會(huì)打Log提醒

  RecyclerView does not support scrolling to an absolute position "Use scrollToPosition instead

第二種方法

到現(xiàn)在就已經(jīng)是實(shí)現(xiàn)RecyclerView 的自動(dòng)滾動(dòng)效果了羡玛,但是有沒有其他方法可以實(shí)現(xiàn)呢?當(dāng)然有 全跨,那就是使用屬性動(dòng)畫來實(shí)現(xiàn)缝左。

屬性動(dòng)畫我們大家都知道,分為兩種重要的類浓若,分別為ValueAnimator 和 ObjectAnimator,ValueAnimator 就是來計(jì)算我們給的初始值和結(jié)束值說白了就是對(duì)值進(jìn)行計(jì)算來完成數(shù)值之間的過度動(dòng)畫 蛇数,而ObjectAnimator不僅會(huì)對(duì)值進(jìn)行計(jì)算還會(huì)通過反射的方式把計(jì)算出來的值賦值給做動(dòng)畫對(duì)象的屬性挪钓,這里我只是說個(gè)大概,但是你有沒有發(fā)現(xiàn)其實(shí)之前的Scroller也是我們給個(gè)開始位置 和結(jié)束為止 他來給我們計(jì)算數(shù)值 然后我們?cè)趕crollBy過去 你會(huì)發(fā)現(xiàn)這個(gè)計(jì)算值的過程跟上面的ValueAnimator 是不是老像了耳舅? 好 那我們就來試試 看看行不行碌上。

//默認(rèn)從0-200 valueAnimator = ValueAnimator.ofInt(200); valueAnimator.setDuration(5000); valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override publicvoidonAnimationUpdate(ValueAnimatoranimation) { //獲取估值器給我們的返回值 int animatedValue = (int) animation.getAnimatedValue(); //調(diào)用RecyclerView的scrollBy執(zhí)行滑動(dòng) recyclerView.scrollBy(0, animatedValue); Log.e("TAG", "animatedValue:" + animatedValue); } } ); valueAnimator.start();

你會(huì)發(fā)現(xiàn)效果是一樣一樣的 倚评,但是實(shí)驗(yàn)到這里 我想悲哀的告訴大家,這里面有個(gè)Bug馏予,細(xì)心的可能發(fā)現(xiàn)了天梧,當(dāng)我們不論是用上面那種方法,當(dāng)你的Item內(nèi)容比較少霞丧,而我們的結(jié)束值又是隨便設(shè)置的呢岗,執(zhí)行時(shí)間稍微長(zhǎng)一點(diǎn) 你就會(huì)發(fā)現(xiàn),哎蛹尝?我怎么不能往上面滑動(dòng)了后豫,但等一會(huì)又可以滑動(dòng)了,其實(shí)是這個(gè)scrollBy還沒有執(zhí)行完突那, 還在往下滑動(dòng)挫酿,只不過是滑動(dòng)到頭了,你看不見罷了 愕难,那又怎么決解這個(gè)問題呢 早龟?其實(shí)RecyclerView有一個(gè)監(jiān)聽 addOnScrollListener 如果你沒有這個(gè)方法 說明你該更新了RecyclerView了 這個(gè)監(jiān)聽有兩個(gè)回掉。

  1. onScrollStateChanged 滑動(dòng)狀態(tài) 兩個(gè)參數(shù)一個(gè)View 一個(gè)狀態(tài) 分為按下滑動(dòng) 和抬起 和MotionEvent 是一樣的 猫缭。
  2. onScrolled 三個(gè)參數(shù) View 和 x,y軸滑動(dòng)的量葱弟。

其實(shí)通過這兩個(gè)回掉很簡(jiǎn)單的就能解決這個(gè)問題 就是我們只要能判斷出當(dāng)前這個(gè)RecyclerView 是不是滑動(dòng)到底部就行了 在onScrollStateChanged中判斷? 當(dāng)滑動(dòng)的狀態(tài)為抬起的時(shí)候我們判斷 不行 因?yàn)槲覀兪鞘褂胹crollBy方法進(jìn)行的滑動(dòng) 妹的 這個(gè)方法根本就不會(huì)執(zhí)行 他只有你手指滑動(dòng)的時(shí)候才會(huì)執(zhí)行饵骨,那咋辦 只有在onScrolled 中判斷了 這個(gè)方法才不會(huì)管你什么滑動(dòng)呢 只要我動(dòng)了 他就執(zhí)行 那怎判斷呢翘悉?
(直接圖片了 代碼這個(gè)格式真心沒弄好 怎么弄都不行 !)

Paste_Image.png
Paste_Image.png
Paste_Image.png

大概的過程就是 居触,我開始執(zhí)行動(dòng)畫 妖混,然后不斷判斷是否達(dá)到最底部 ,不是得話就繼續(xù)執(zhí)行滑動(dòng)轮洋。這時(shí)候呢制市,因?yàn)槲冶O(jiān)聽了RecyclerVIew的滑動(dòng) 一滑動(dòng)我就判斷。
怎么判斷呢弊予?得到當(dāng)前顯示的最后一個(gè)item的view祥楣,通過這個(gè)View 得到他的bottom坐標(biāo)值,然后在獲得RecyclerView的bottom坐標(biāo)值汉柒,在拿到最后View的position误褪,在拿到RecyclerView item的總數(shù)-1,他們四個(gè)進(jìn)行比較碾褂。 都滿足了兽间,就能說明,當(dāng)前已經(jīng)滑動(dòng)到最底部了正塌,這時(shí)候給isBottom賦值為True 嘀略,接著動(dòng)畫監(jiān)聽里面我們之前不是做了判斷么恤溶!滿足else條件 取消動(dòng)畫,就不會(huì)在執(zhí)行了帜羊,那個(gè)Bug也就解決了咒程。
  但是現(xiàn)在這個(gè)方法還有效率問題,滑動(dòng)就執(zhí)行判斷讼育,而且還是獲取View的各種信息帐姻,想辦法在優(yōu)化吧。還有一個(gè)就是窥淆,如果我們能知道具體移動(dòng)到什么位置就好了 ,我們上面設(shè)置的是200,因?yàn)檫@個(gè)參數(shù)是坐標(biāo),而RecyclerView的內(nèi)容其實(shí)已經(jīng)超過屏幕坐標(biāo)系了,這個(gè)問題待解決卖宠。。忧饭。扛伍。

好了 以上就是我總結(jié)的一些開發(fā)中的經(jīng)驗(yàn) 如果有誰能知道解決這個(gè)辦法 和寫的不對(duì)的地方 歡迎指教 。词裤。刺洒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吼砂,隨后出現(xiàn)的幾起案子逆航,更是在濱河造成了極大的恐慌,老刑警劉巖渔肩,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件因俐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡周偎,警方通過查閱死者的電腦和手機(jī)抹剩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蓉坎,“玉大人澳眷,你說我怎么就攤上這事◎劝” “怎么了钳踊?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)勿侯。 經(jīng)常有香客問我拓瞪,道長(zhǎng),這世上最難降的妖魔是什么助琐? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任吴藻,我火速辦了婚禮,結(jié)果婚禮上弓柱,老公的妹妹穿的比我還像新娘沟堡。我一直安慰自己,他們只是感情好矢空,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布航罗。 她就那樣靜靜地躺著,像睡著了一般屁药。 火紅的嫁衣襯著肌膚如雪粥血。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天酿箭,我揣著相機(jī)與錄音复亏,去河邊找鬼。 笑死缭嫡,一個(gè)胖子當(dāng)著我的面吹牛缔御,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妇蛀,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼耕突,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了评架?” 一聲冷哼從身側(cè)響起眷茁,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纵诞,沒想到半個(gè)月后上祈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浙芙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年登刺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茁裙。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡塘砸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晤锥,到底是詐尸還是另有隱情掉蔬,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布矾瘾,位于F島的核電站女轿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏壕翩。R本人自食惡果不足惜蛉迹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望放妈。 院中可真熱鬧北救,春花似錦荐操、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至攘宙,卻和暖如春屯耸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蹭劈。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工疗绣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铺韧。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓多矮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親祟蚀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子工窍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,732評(píng)論 25 707
  • 簡(jiǎn)介: 提供一個(gè)讓有限的窗口變成一個(gè)大數(shù)據(jù)集的靈活視圖。 術(shù)語表: Adapter:RecyclerView的子類...
    酷泡泡閱讀 5,148評(píng)論 0 16
  • 簡(jiǎn)介 RecyclerView在24.2.0版本中新增了SnapHelper這個(gè)輔助類前酿,用于輔助RecyclerV...
    辰之貓閱讀 154,239評(píng)論 65 617
  • 這篇文章分三個(gè)部分患雏,簡(jiǎn)單跟大家講一下 RecyclerView 的常用方法與奇葩用法;工作原理與ListView比...
    LucasAdam閱讀 4,377評(píng)論 0 27
  • 在真正進(jìn)入寺廟核心之前罢维,我們被幻影迷惑了淹仑,真相還在遠(yuǎn)方。如果“迷”是過程肺孵,我們似乎離“悟”還遠(yuǎn)…… ...
    斜月三星洞_心容閱讀 376評(píng)論 0 1