恢复 RecyclerView 的滚动位置
您可能在开发过程中遇到过这种情况,在 Activity/Fragment 被重新创建后,RecyclerView 丢失了它之前保有的滚动位置信息。通常这种情况发生的原因是由于异步加载 Adapter 数据,且数据在 RecyclerView 需要进行布局的时候尚未加载完成,导致 RecyclerView 无法恢复到之前的滚动位置。
从 1.2.0-alpha02 版本开始,Jetpack RecyclerView 提供了一个新的 API,可以让 Adapter 在数据加载完成之前阻塞布局行为,从而避免丢失滚动位置信息。接下来我们会介绍如何使用这个新的 API,以及它的工作原理。
-
1.2.0-alpha02 版本
https://developer.android.google.cn/jetpack/androidx/releases/recyclerview
恢复至原有滚动位置
有好几种方法可以用来恢复 RecyclerView 至正确的滚动位置,您可能已经在实际项目中用到了这些方法。其中最好的一种方法是将数据提前缓存在内存、ViewModel 或 Repository 中,然后确保在第一次布局传入之前,将缓存的数据设置到 Adapter 中去。如果根据您的项目实际情况无法采用这种方法,那也可以使用其他的方法,只是要么比较复杂 (比如避免在 RecyclerView 中设置 Adapter,但这样又有可能导致像 header 等 item 的显示问题),要么会导致 LayoutManager.onRestoreInstanceState API 被滥用。
-
LayoutManager.onRestoreInstanceState
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.LayoutManager?hl=en#onRestoreInstanceState(android.os.Parcelable)
recyclerview:1.2.0-alpha02 版本中提供的解决方案是引入一个新的 Adapter 方法,来允许您设置它的状态恢复策略 (通过枚举类型 StateRestorationPolicy)。它有三个选项:
ALLOW — 默认状态,会在下一次布局完成时立即恢复 RecyclerView 状态;
PREVENT_WHEN_EMPTY — 仅当 adapter 不为空 (即 adapter.getItemCount() > 0) 的时候,才恢复 RecyclerView 的状态。如果您是异步加载数据,RecyclerView 会等待数据加载完毕之后,才对状态进行恢复。如果在 Adapter 中有一些默认的 item,比如 header 或是 load progress indicator,那您应该使用 PREVENT 选项,除非是通过 ConcatAdapter 添加默认的 item,了解更多详细信息,请查阅《使用 ConcatAdapter 顺序连接其他 Adapter》。ConcatAdapter 会等待所有的 adapter 全部准备就绪后,才进行状态的恢复;
PREVENT — 所有的状态恢复都会等到您设置了 ALLOW 或者 PREVENT_WHEN_EMPTY 选项,才会得到执行。
-
StateRestorationPolicy
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter.StateRestorationPolicy
-
ALLOW
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter.StateRestorationPolicy#ALLOW
-
PREVENT_WHEN_EMPTY
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter.StateRestorationPolicy#PREVENT_WHEN_EMPTY
-
ConcatAdapter
https://developer.android.google.cn/reference/androidx/recyclerview/widget/ConcatAdapter
-
PREVENT
https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter.StateRestorationPolicy#PREVENT
通过如下示例代码可设置 adapter 的状态恢复策略:
adapter.stateRestorationPolicy = PREVENT_WHEN_EMPTY
通过这篇短小精悍的文章您可以了解到关于 RecyclerView 的延迟状态恢复 (lazy state restoration) 功能。赶快开始使用吧!
推荐阅读
点击屏末 | 阅读原文 | 使用 RecyclerView 创建列表
本文地址:https://blog.csdn.net/jILRvRTrc/article/details/108819456