Управление состоянием RecyclerView

RecyclerView может отображать большие объемы данных, используя минимум графических ресурсов. Когда пользователи прокручивают элементы в RecyclerView , экземпляры View элементов, которые прокрутились за пределы экрана, повторно используются для создания новых элементов по мере их прокрутки на экране. Но изменения конфигурации, такие как поворот устройства, могут сбросить состояние RecyclerView , заставляя пользователей снова прокручивать их до предыдущей позиции в списке элементов.

RecyclerView должен сохранять свое состояние, в частности положение прокрутки, и состояние элементов своего списка во время всех изменений конфигурации.

Поддерживать состояние

Установите политику восстановления состояния RecyclerView.Adapter , чтобы сохранить положение прокрутки RecyclerView . Сохраните состояние элементов списка RecyclerView . Добавьте состояние элементов списка в адаптер RecyclerView и восстановите состояние элементов списка, когда они привязаны к ViewHolder .

1. Включите политику восстановления состояния Adapter .

Включите политику восстановления состояния адаптера RecyclerView , чтобы положение прокрутки RecyclerView сохранялось при изменении конфигурации. Добавьте спецификацию политики в конструктор адаптера:

Котлин

class MyAdapter() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    init {
        stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
    }
    ...
}

Ява

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.
        }
    }
)

Ява

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())

Ява

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)
    }
}

Ява

@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 : сохраняет состояние действия или фрагмента.

Результаты

Теперь ваш RecyclerView может восстановить положение прокрутки и состояние каждого элемента в списке RecyclerView .

Коллекции, содержащие это руководство

Это руководство является частью тщательно подобранной коллекции быстрых руководств, охватывающих более широкие цели разработки Android:

Включите свое приложение для поддержки оптимизированного взаимодействия с пользователем на планшетах, складных устройствах и устройствах ChromeOS.

Есть вопросы или отзывы

Перейдите на нашу страницу часто задаваемых вопросов и узнайте о кратких руководствах или свяжитесь с нами и сообщите нам свои мысли.