RecyclerViewのスクロール位置の復元

StateRestorationPolicyで復元の制御

Kenji Abe
3 min readAug 16, 2020
Photo by Christian Wiediger on Unsplash

ActivityやFragmentが回転や遷移などで再生成された際に、RecyclerViewのスクロール位置がうまく復元できない時があります。

ViewModelなどを使ってキャッシュしている場合などは、RecyclerViewがスクロール位置を復元する前にデータをセットしてるので、位置を復元することが可能でした。

しかし、ViewModelなどのキャッシュが使えず、RecyclerViewが復元処理をしたあとにデータをセットするしかない場合などはスクロール位置を復元するのは難しい状態です。

RecyclerView: 1.2.0-alpha02 から StateRestorationPolicy が導入され、復元のタイミングを制御できるようになりました。

StateRestorationPolicy

StateRestorationPolicy には3種類あります。

  • ALLOW : これは通常通りすぐに復元されるものです。何も指定しなければ、これがデフォルトになります。
  • PREVENT_WHEN_EMPTY : Adapterのデータが0件であれば復元せず、1件以上になったときに復元されます。
  • PREVENT : これは復元をしません。復元を実行するには、 ALLOWPREVENT_WHEN_EMPTY を手動で呼ぶ必要があります。

使い方

使い方は簡単です。Adapterの stateRestorationPolicy にセットするだけです。

adapter.stateRestorationPolicy =
RecyclerView.Adapter.StateRestorationPolicy.PREVENT

動きの確認

ちょっとコードだけだと分かりにくいと思うので、わざとスクロール位置が復元されない再現コードを使いながら見ていきます。

ALLOW

まずはデフォルトのALLOWの動きです。
最初に下までスクロールしてますが、横に回転したあとはスクロール位置が一番上に戻っています。

ALLOW

PREVENT_WHEN_EMPTY

次に0件のときは、復元しない設定です。
ALLOWのときと違って、横に回転したあとにスクロール位置が戻っています。

PREVENT_WHEN_EMPTY

PREVENT

最後に復元しない設定です。手動で復元を実行するようにコードを以下のように少し変えます。

この場合、横回転してデータが表示されて遅れてスクロール位置が復元されています。

PREVENT

このように、復元のタイミングを簡単に制御できるようになりました。

--

--

Kenji Abe
Kenji Abe

Written by Kenji Abe

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO

No responses yet