RecyclerView恢復(fù)瀏覽位置一些事

Android做應(yīng)用不免需要使用到列表窍仰,說到列表岩四,大部分人會(huì)想到ListView恭朗,當(dāng)然現(xiàn)在也有很多人會(huì)想到RecyclerView屏镊,因?yàn)楫吘故枪雀韫俜酵扑]嘛,什么定制性更高痰腮,功能更強(qiáng)而芥,更高效。

實(shí)話說膀值,ListView對(duì)于大部分人來說棍丐,足夠用了,因?yàn)楫吘故煜ecyclerView需要時(shí)間沧踏,RecyclerView也有一些不大不小的坑歌逢。不管怎么說,我在項(xiàng)目中用上了RecyclerView翘狱,本沒什么秘案,跟ListView一樣,現(xiàn)主要介紹下這幾天使用RecyclerView碰到的事潦匈,也希望其他人少走彎路阱高。

情況是這樣子的,我們需要對(duì)頁面中整個(gè)數(shù)據(jù)緩存历等,并記錄用戶瀏覽位置讨惩,下次用戶再次進(jìn)入當(dāng)前頁面時(shí)辟癌,能定位到之前的瀏覽位置寒屯,很好的用戶體驗(yàn),開始做...

關(guān)于數(shù)據(jù)緩存黍少,我們是使用Realm存儲(chǔ)的寡夹,Realm確實(shí)神器啊,傻瓜式操作厂置,增刪減查菩掏,幾句代碼搞定,不用像android原生數(shù)據(jù)庫(kù)一樣昵济,所有的都要自己實(shí)現(xiàn)智绸。一開始的邏輯是,在退出頁面時(shí)访忿,使用Realm記錄當(dāng)前頁面所有數(shù)據(jù)瞧栗,并記錄用戶滑動(dòng)的位置;當(dāng)用戶重新進(jìn)入頁面時(shí)海铆,讀取數(shù)據(jù)庫(kù)數(shù)據(jù)迹恐,加載到RecyclerView中,然后滑動(dòng)到上次瀏覽位置卧斟。

當(dāng)數(shù)據(jù)少時(shí)殴边,這樣做確實(shí)沒問題憎茂,上面的操作基本在幾十毫秒內(nèi)解決,但是一旦數(shù)據(jù)上百或幾百條時(shí)锤岸,Realm讀取數(shù)據(jù)時(shí)間明顯增加竖幔,RecylcerView加載數(shù)據(jù)時(shí)間也相應(yīng)增加,最關(guān)鍵的是滑動(dòng)到上次瀏覽位置時(shí)是偷,能明顯看到滑動(dòng)動(dòng)畫赏枚,當(dāng)然我用的滑動(dòng)方法時(shí)下面這個(gè)

recyclerView.post(new Runnable() {    
   @Override    
   public void run() {        
       recyclerView.scrollBy(0, 100);    
   }
});

事后證明我用的這個(gè)滑動(dòng)方法也有問題,當(dāng)然這是后話晓猛。

實(shí)際證明饿幅,這種實(shí)現(xiàn)緩存并滑動(dòng)到瀏覽位置的方案行不通。然后一通的谷歌戒职,百度栗恩,然后又是看到一大堆博客類似上面代碼方式,很無奈...

這時(shí)候洪燥,IOS大哥過來跟我說磕秤,它們可以存儲(chǔ)整個(gè)頁面,然后再次進(jìn)頁面的時(shí)候只要重新加載這個(gè)存儲(chǔ)的頁面就好捧韵,是不是so easy市咆,沒有數(shù)據(jù)庫(kù)緩存,沒有RecyclerView滑動(dòng)這回事再来;我就估摸著蒙兰,Android是不是可以存儲(chǔ)整個(gè)Activity呢?想到就做芒篷,確實(shí)可以保存整個(gè)Activity搜变,但是怎么加入到當(dāng)前的Activity棧中呢?開始查資料针炉,繼續(xù)一通谷歌百度挠他,然而好像還是不知道怎么加(有知道的哥們希望告訴下),倒是額外學(xué)到了一個(gè)很有用的方法moveTaskToBack()篡帕,算是浪費(fèi)時(shí)間的補(bǔ)償吧殖侵。

又一條路不通,開始意識(shí)到是不是陷入死胡同了镰烧,有些煩了拢军,刷知乎吧,本著鳥槍法的原則拌滋,不經(jīng)意的在知乎也搜了關(guān)于這個(gè)問題的方案朴沿,看了十幾篇好像也沒什么用,快失望的時(shí)候,突然看到一句評(píng)論:緩存Fragment赌渣∥呵Γ看到這句評(píng)論的時(shí)候,真有種熱淚盈眶的感覺坚芜,是啊览芳,緩存整個(gè)Activity行不通,緩存Fragment總行吧鸿竖,想到就做沧竟,每當(dāng)用戶退出當(dāng)前頁面時(shí),在內(nèi)存中緩存當(dāng)前Fragment缚忧,下次進(jìn)這個(gè)頁面時(shí)悟泵,直接加載這個(gè)Fragment,實(shí)驗(yàn)很成功闪水,進(jìn)入頁面直接就在上次瀏覽位置糕非,不會(huì)出現(xiàn)滑動(dòng)動(dòng)畫,完美實(shí)現(xiàn)需要的效果(當(dāng)然加載這個(gè)緩存的Fragment時(shí)球榆,里面涉及到Activity的對(duì)象全部需要重新加載)朽肥。

按理說,事情到這里應(yīng)該就完了持钉。但是不對(duì)衡招,緩存的Fragment帶有Activity的引用(雖然這個(gè)Activity已經(jīng)在退出時(shí)被銷毀了),不會(huì)釋放每强,會(huì)造成內(nèi)存泄露始腾,出了問題就解唄,然而研究一通發(fā)現(xiàn)舀射,要緩存整個(gè)Fragment窘茁,這個(gè)內(nèi)存泄露的問題必定會(huì)出現(xiàn)怀伦,最后也未發(fā)現(xiàn)解決的方法脆烟,就暫時(shí)擱置了。

雖然擱置這件事房待,但內(nèi)心總有心疙瘩邢羔,瀏覽技術(shù)網(wǎng)站時(shí),總是時(shí)不時(shí)的會(huì)搜索關(guān)于這個(gè)問題的解決方法桑孩,無意中發(fā)現(xiàn)ListView存在一個(gè)方法setSelectionFromTop可以直接直接回到瀏覽位置拜鹤;既然ListView有這個(gè)方法,RecyclerView應(yīng)該也有吧流椒?然而查詢之后敏簿,發(fā)現(xiàn)那只是我的意淫;不過,沒這個(gè)方法惯裕,也并沒有放棄温数,RecyclerView既然是可以替代ListView的,總覺得是有和setSelectionFromTop相同功能的方法的蜻势,最后也確實(shí)找出了撑刺,scrollToPositionWithOffset,嗯握玛,好像不再RecyclerView里面够傍,去LinearLayoutManager里面試試,終于找到挠铲!

它有2個(gè)參數(shù)冕屯,第一個(gè)參數(shù)代表你要滑動(dòng)到哪個(gè)Item,第二個(gè)參數(shù)代表這個(gè)item距離屏幕頂部的距離拂苹,這個(gè)距離可以使用下面代碼計(jì)算得出:

int position = linearLayoutManager.findFirstVisibleItemPosition();
View view = recyclerView.getChildAt(position);
if (view != null) {    
   int top = view.getTop();
}

ok愕撰,實(shí)現(xiàn)了效果,不卡頓醋寝,也不會(huì)有滑動(dòng)動(dòng)畫搞挣,也不會(huì)出現(xiàn)內(nèi)存泄露,問題解決了嘛音羞?

這次是徹底解決了囱桨,以上記錄苦逼的繞坑過程,那么多的研究嗅绰,發(fā)現(xiàn)最后一個(gè)scrollToPositionWithOffset就解決了舍肠,是不是很崩潰?我確實(shí)崩潰了窘面。

最后翠语,希望技術(shù)博客的轉(zhuǎn)載哥哥們,轉(zhuǎn)載之前自己試試效果吧财边,因?yàn)橛袝r(shí)候真的挺坑人的肌括!哭!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末酣难,一起剝皮案震驚了整個(gè)濱河市谍夭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌憨募,老刑警劉巖紧索,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異菜谣,居然都是意外死亡珠漂,警方通過查閱死者的電腦和手機(jī)晚缩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來媳危,“玉大人橡羞,你說我怎么就攤上這事〖糜撸” “怎么了卿泽?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滋觉。 經(jīng)常有香客問我签夭,道長(zhǎng),這世上最難降的妖魔是什么椎侠? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任第租,我火速辦了婚禮,結(jié)果婚禮上我纪,老公的妹妹穿的比我還像新娘慎宾。我一直安慰自己,他們只是感情好浅悉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布趟据。 她就那樣靜靜地躺著,像睡著了一般术健。 火紅的嫁衣襯著肌膚如雪汹碱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天荞估,我揣著相機(jī)與錄音咳促,去河邊找鬼。 笑死勘伺,一個(gè)胖子當(dāng)著我的面吹牛跪腹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播飞醉,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼冲茸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了冒掌?” 一聲冷哼從身側(cè)響起噪裕,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎股毫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體召衔,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡铃诬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趣席。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兵志,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宣肚,到底是詐尸還是另有隱情想罕,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布霉涨,位于F島的核電站按价,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏笙瑟。R本人自食惡果不足惜楼镐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望往枷。 院中可真熱鬧框产,春花似錦、人聲如沸错洁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屯碴。三九已至蘸鲸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窿锉,已是汗流浹背酌摇。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嗡载,地道東北人窑多。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洼滚,于是被迫代替她去往敵國(guó)和親埂息。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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