RecyclerView 可以使用尽可能少的图形资源显示大量数据。当用户滚动浏览 RecyclerView 中的项时,系统会重复使用已滚出屏幕的项的 View 实例来创建滚入屏幕中的新项。但是,配置更改(例如设备旋转)可以重置 RecyclerView 的状态,迫使用户重新滚动到之前在项列表中的位置。
RecyclerView 应在所有配置更改期间保持其状态(特别是滚动位置)及其列表元素的状态。
结果
您的 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.Adapter#setStateRestorationPolicy():指定RecyclerView.Adapter在配置更改后如何恢复其状态。ViewModel:保持 activity 或 fragment 的状态。
包含本指南的集合
本指南属于以下精选的快速指南合集,这些合集涵盖了更广泛的 Android 开发目标: