管理 RecyclerView 状态
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
RecyclerView
可以使用尽可能少的图形资源显示大量数据。当用户滚动浏览 RecyclerView
中的项时,系统会重复使用已滚动到界面外的项的 View
实例,随着项在屏幕上滚动而创建新的项。但是,配置更改(例如设备旋转)可以重置 RecyclerView
的状态,迫使用户重新滚动到之前在项列表中的位置。
RecyclerView
应在所有配置更改期间保持其状态(特别是滚动位置)及其列表元素的状态。
保持状态
设置 RecyclerView.Adapter
的状态恢复政策以保存 RecyclerView
滚动位置。保存 RecyclerView
列表项的状态。将列表项的状态添加到 RecyclerView
适配器,并在列表项绑定到 ViewHolder
后恢复其状态。
1. 启用 Adapter
状态恢复政策
启用 RecyclerView
适配器的状态恢复政策,以便在遇到各种配置更改时保持 RecyclerView
的滚动位置。将政策规范添加到适配器构造函数:
Kotlin
class MyAdapter() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
init {
stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
}
...
}
Java
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public Adapter() {
setStateRestorationPolicy(StateRestorationPolicy.PREVENT_WHEN_EMPTY);
}
...
}
2. 保存有状态列表项的状态
保存复杂 RecyclerView
列表项(例如包含 EditText
元素的项)的状态。例如,如需保存 EditText
的状态,请添加类似于 onClick
处理程序的回调来捕获文本更改。在回调中,定义要保存的数据:
Kotlin
input.addTextChangedListener(
afterTextChanged = { text ->
text?.let {
// Save state here.
}
}
)
Java
input.addTextChangedListener(new TextWatcher() {
...
@Override
public void afterTextChanged(Editable s) {
// Save state here.
}
});
在 Activity
或 Fragment
中声明回调。使用 ViewModel
存储状态。
3. 将列表项状态添加到 Adapter
将列表项的状态添加到 RecyclerView.Adapter
。在您的主机 Activity
或 Fragment
被创建后,将项状态传递到适配器构造函数:
Kotlin
val adapter = MyAdapter(items, viewModel.retrieveState())
Java
MyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());
4. 在适配器的 ViewHolder
中恢复列表项状态
在 RecyclerView.Adapter
中,当您将 ViewHolder
绑定到某个项后,恢复此项的状态:
Kotlin
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
...
val item = items[position]
val state = states.firstOrNull { it.item == item }
if (state != null) {
holder.restore(state)
}
}
Java
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
...
Item item = items[position];
Arrays.stream(states).filter(state -> state.item == item)
.findFirst()
.ifPresent(state -> holder.restore(state));
}
要点
结果
现在,您的 RecyclerView
能够恢复其滚动位置以及 RecyclerView
列表中每个项的状态。
包含本指南的集合
本指南属于以下精选快速入门指南集合,这些指南涵盖了更广泛的 Android 开发目标:
针对大屏设备进行优化
让您的应用能够在平板电脑、可折叠设备和 ChromeOS 设备上提供优化的用户体验。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-02-06。
[null,null,["最后更新时间 (UTC):2025-02-06。"],[],[],null,["# Manage RecyclerView state\n\n\u003cbr /\u003e\n\n[`RecyclerView`](/reference/kotlin/androidx/recyclerview/widget/RecyclerView) can display large amounts of data using minimal graphical\nresources. As users scroll through the items in a `RecyclerView`, `View`\ninstances of items that have scrolled off screen are reused to create new items\nas they scroll on screen. But configuration changes, such as device rotation,\ncan reset the state of a `RecyclerView`, forcing users to again scroll to their\nprevious position in the list of items.\n\n`RecyclerView` should maintain its state---in particular, scroll\nposition---and the state of its list elements during all configuration\nchanges.\n\nMaintain state\n--------------\n\nSet the state restoration policy of the `RecyclerView.Adapter` to save the\n`RecyclerView` scroll position. Save the state of `RecyclerView` list items. Add\nthe state of the list items to the `RecyclerView` adapter, and restore the state\nof list items when they're bound to a `ViewHolder`.\n\n### 1. Enable `Adapter` state restoration policy\n\nEnable the state restoration policy of the `RecyclerView` adapter so that the\nscrolling position of the `RecyclerView` is maintained across configuration\nchanges. Add the policy specification to the adapter constructor: \n\n### Kotlin\n\n```kotlin\nclass MyAdapter() : RecyclerView.Adapter\u003cRecyclerView.ViewHolder\u003e() {\n init {\n stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY\n }\n ...\n}\n```\n\n### Java\n\n```java\nclass MyAdapter extends RecyclerView.Adapter\u003cRecyclerView.ViewHolder\u003e {\n\n public Adapter() {\n setStateRestorationPolicy(StateRestorationPolicy.PREVENT_WHEN_EMPTY);\n }\n ...\n}\n```\n\n### 2. Save the state of stateful list items\n\nSave the state of complex `RecyclerView` list items, such as items that contain\n`EditText` elements. For example, to save the state of an `EditText`, add a\ncallback similar to an `onClick` handler to capture text changes. Within the\ncallback, define what data to save: \n\n### Kotlin\n\n```kotlin\ninput.addTextChangedListener(\n afterTextChanged = { text -\u003e\n text?.let {\n // Save state here.\n }\n }\n)\n```\n\n### Java\n\n```java\ninput.addTextChangedListener(new TextWatcher() {\n\n ...\n\n @Override\n public void afterTextChanged(Editable s) {\n // Save state here.\n }\n});\n```\n\nDeclare the callback in your `Activity` or `Fragment`. Use a `ViewModel` to\nstore the state.\n\n### 3. Add list item state to the `Adapter`\n\nAdd the state of list items to your `RecyclerView.Adapter`. Pass the item state\nto the adapter constructor when your host `Activity` or `Fragment` is created: \n\n### Kotlin\n\n```kotlin\nval adapter = MyAdapter(items, viewModel.retrieveState())\n```\n\n### Java\n\n```java\nMyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());\n```\n\n### 4. Recover list item state in the adapter's `ViewHolder`\n\nIn the `RecyclerView.Adapter`, when you bind a [`ViewHolder`](/reference/kotlin/androidx/recyclerview/widget/RecyclerView.ViewHolder) to an item,\nrestore the item's state: \n\n### Kotlin\n\n```kotlin\noverride fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n ...\n val item = items[position]\n val state = states.firstOrNull { it.item == item }\n\n if (state != null) {\n holder.restore(state)\n }\n}\n```\n\n### Java\n\n```java\n@Override\npublic void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {\n ...\n Item item = items[position];\n Arrays.stream(states).filter(state -\u003e state.item == item)\n .findFirst()\n .ifPresent(state -\u003e holder.restore(state));\n}\n```\n\nKey points\n----------\n\n- [`RecyclerView.Adapter#setStateRestorationPolicy()`](/reference/kotlin/androidx/recyclerview/widget/RecyclerView.Adapter.StateRestorationPolicy): Specifies how a `RecyclerView.Adapter` restores its state after a configuration change.\n- [`ViewModel`](/reference/kotlin/androidx/lifecycle/ViewModel): Holds state for an activity or fragment.\n\nResults\n-------\n\nYour `RecyclerView` is now able to restore its scroll position and the state of\nevery item in the `RecyclerView` list.\n\nCollections that contain this guide\n-----------------------------------\n\nThis guide is part of these curated Quick Guide collections that cover broader\nAndroid development goals: \n\n### Optimize for large screens\n\nEnable your app to support an optimized user experience on tablets, foldables, and ChromeOS devices. \n[Quick guide collection](/quick-guides/collections/optimize-for-large-screens) \n\nHave questions or feedback\n--------------------------\n\nGo to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts. \n[Go to FAQ](/quick-guides/faq) [Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)"]]