RecyclerView может отображать большие объемы данных, используя минимальные графические ресурсы. По мере прокрутки элементов в RecyclerView , экземпляры View элементов, которые уже покинули экран, повторно используются для создания новых элементов по мере их появления на экране. Однако изменения конфигурации, такие как поворот устройства, могут сбросить состояние RecyclerView , заставляя пользователей снова прокручивать список элементов до их предыдущего положения.
RecyclerView должен сохранять свое состояние — в частности, положение прокрутки — и состояние элементов списка при всех изменениях конфигурации.
Результаты
Ваш RecyclerView способен восстанавливать положение прокрутки и состояние каждого элемента в списке RecyclerView .
Совместимость версий
Данная реализация совместима со всеми уровнями API.
Зависимости
Никто.
Поддерживать состояние
Установите политику восстановления состояния RecyclerView.Adapter таким образом, чтобы она сохраняла положение прокрутки RecyclerView . Сохраните состояние элементов списка RecyclerView . Добавьте состояние элементов списка в адаптер RecyclerView и восстановите состояние элементов списка, когда они будут привязаны к ViewHolder .
1. Включите политику восстановления состояния Adapter .
Включите политику восстановления состояния адаптера RecyclerView , чтобы положение прокрутки RecyclerView сохранялось при изменении конфигурации. Добавьте спецификацию политики в конструктор адаптера:
Котлин
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 для отслеживания изменений текста. Внутри функции обратного вызова определите, какие данные следует сохранить:
Котлин
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 :
Котлин
val adapter = MyAdapter(items, viewModel.retrieveState())
Java
MyAdapter adapter = new MyAdapter(items, viewModel.retrieveState());
4. Восстановить состояние элемента списка в ViewHolder адаптера.
В RecyclerView.Adapter при привязке ViewHolder к элементу необходимо восстановить состояние элемента:
Котлин
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: хранит состояние активности или фрагмента.
Коллекции, содержащие это руководство
Данное руководство является частью подборки кратких руководств, охватывающих более широкие цели разработки под Android:
