RecyclerView では、最小限のグラフィック リソースを使用して大量のデータを表示できます。ユーザーが RecyclerView 内のアイテムをスクロールすると、View
画面外にスクロールしたアイテムのインスタンスが再利用され、新しいアイテムが作成されます
画面上でのスクロール時。しかし、デバイスの回転などの構成変更により、RecyclerView の状態がリセットされ、ユーザーがアイテムのリストの以前の位置に再びスクロールしなければならない場合があります。
RecyclerView は、すべての構成変更において、状態(特にスクロール位置)とリスト要素の状態を維持する必要があります。
結果
RecyclerView は、スクロール位置と RecyclerView リスト内のすべてのアイテムの状態を復元できるようになりました。
バージョンの互換性
この実装はすべての API レベルと互換性があります。
依存関係
なし。
状態の維持
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. ステートフルなリストアイテムの状態を保存する
EditText 要素を含むアイテムなど、複雑な RecyclerView リストアイテムの状態を保存します。たとえば、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: アクティビティまたはフラグメントの状態を保持します。
このガイドを含むコレクション
このガイドは、Android デベロッパーの広範な目標をカバーする、厳選されたクイック ガイド コレクションの一部です。