恢復(fù) RecyclerView 的滾動(dòng)位置

image

您可能在開發(fā)過(guò)程中遇到過(guò)這種情況,在 Activity/Fragment 被重新創(chuàng)建后,RecyclerView 丟失了它之前保有的滾動(dòng)位置信息。通常這種情況發(fā)生的原因是由于異步加載 Adapter 數(shù)據(jù),且數(shù)據(jù)在 RecyclerView 需要進(jìn)行布局的時(shí)候尚未加載完成,導(dǎo)致 RecyclerView 無(wú)法恢復(fù)到之前的滾動(dòng)位置。

1.2.0-alpha02 版本開始,Jetpack RecyclerView 提供了一個(gè)新的 API,可以讓 Adapter 在數(shù)據(jù)加載完成之前阻塞布局行為 ,從而避免丟失滾動(dòng)位置信息。接下來(lái)我們會(huì)介紹如何使用這個(gè)新的 API,以及它的工作原理。

恢復(fù)至原有滾動(dòng)位置

有好幾種方法可以用來(lái)恢復(fù) RecyclerView 至正確的滾動(dòng)位置,您可能已經(jīng)在實(shí)際項(xiàng)目中用到了這些方法。其中最好的一種方法是將數(shù)據(jù)提前緩存在內(nèi)存、ViewModel 或 Repository 中,然后確保在第一次布局傳入之前,將緩存的數(shù)據(jù)設(shè)置到 Adapter 中去。如果根據(jù)您的項(xiàng)目實(shí)際情況無(wú)法采用這種方法,那也可以使用其他的方法,只是要么比較復(fù)雜 (比如避免在 RecyclerView 中設(shè)置 Adapter,但這樣又有可能導(dǎo)致像 header 等 item 的顯示問(wèn)題),要么會(huì)導(dǎo)致 LayoutManager.onRestoreInstanceState API 被濫用。

recyclerview:1.2.0-alpha02 版本中提供的解決方案是引入一個(gè)新的 Adapter 方法,來(lái)允許您設(shè)置它的狀態(tài)恢復(fù)策略 (通過(guò)枚舉類型 StateRestorationPolicy)。它有三個(gè)選項(xiàng):

  • ALLOW — 默認(rèn)狀態(tài),會(huì)在下一次布局完成時(shí)立即恢復(fù) RecyclerView 狀態(tài);
  • PREVENT_WHEN_EMPTY — 僅當(dāng) adapter 不為空 (即 adapter.getItemCount() > 0) 的時(shí)候,才恢復(fù) RecyclerView 的狀態(tài)。如果您是異步加載數(shù)據(jù),RecyclerView 會(huì)等待數(shù)據(jù)加載完畢之后,才對(duì)狀態(tài)進(jìn)行恢復(fù)。如果在 Adapter 中有一些默認(rèn)的 item,比如 header 或是 load progress indicator,那您應(yīng)該使用 PREVENT 選項(xiàng),除非是通過(guò) ConcatAdapter 添加默認(rèn)的 item,了解更多詳細(xì)信息,請(qǐng)查閱《使用 ConcatAdapter 順序連接其他 Adapter》。ConcatAdapter 會(huì)等待所有的 adapter 全部準(zhǔn)備就緒后,才進(jìn)行狀態(tài)的恢復(fù);
  • PREVENT — 所有的狀態(tài)恢復(fù)都會(huì)等到您設(shè)置了 ALLOW 或者 PREVENT_WHEN_EMPTY 選項(xiàng),才會(huì)得到執(zhí)行。

通過(guò)如下示例代碼可設(shè)置 adapter 的狀態(tài)恢復(fù)策略:

adapter.stateRestorationPolicy = PREVENT_WHEN_EMPTY

通過(guò)這篇短小精悍的文章您可以了解到關(guān)于 RecyclerView 的延遲狀態(tài)恢復(fù) (lazy state restoration) 功能。趕快開始使用吧!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容