rememberSaveable と Saver

Kenji Abe
Aug 27, 2022

--

Photo by Tobias Cornille on Unsplash

Composeにおいてrecomposition後も状態を保持するために remember がありますが、画面回転などConfiguration Change後でも状態を保持する rememberSaveable について解説します。

rememberSaveable

単純な値で rememberSaveable を使う場合は remember とほぼ変わりません。

また、 mutableStateOf も同様に使用できます。

これだけでConfiguration Change後も値を復元してくれます。

使用できる型

rememberSaveable はすべての型が使用できるわけではありません。

例えば、上記のように独自のクラスを rememberSaveable で使おうとすると、以下の例外を投げます。

java.lang.IllegalArgumentException: User(name=) cannot be saved using the current SaveableStateRegistry. The default implementation only supports types which can be stored inside the Bundle. Please consider implementing a custom Saver for this class and pass it to rememberSaveable().

rememberSaveable は最終的に ComponentActivity#onSaveInstanceState にて状態を保存するため、 Bundle に保存できるもだけが使用できます。

サポートされてる型は ココのコード で定義されています。
また、MutableState については特別な処理で対応していて、MutableStateで使われてる型のほうがチェックされます。

rememberSaveable に対応する

rememberSaveable に対応するにはいくつかの方法があります。

Parcelable

一番簡単な方法は、独自クラスを Parcelable にするだけです。

これでクラッシュせず rememberSaveable でも使用可能になります。

Saverの実装

単純に Parcelable に対応できない場合は Saver を実装することで対応することもできます。

SaverBundle に保存できる型に変換して、Bundle から復元した値を変換する処理を実装します。 実装したものをrememberSaveablesaver パラメータに渡すことで対応できます。

MutableState を使う場合は stateSaver パラメータのほうに実装した Saver を渡します。

補足ですが、 パラメータを指定しなかった場合はデフォルトの AutoSaver が使用されます。

mapSaver と listSaver

Saver を実装するためのヘルパーメソッドとして、 mapSaverlistSaver が用意されています。
実装としては以下のような感じになります。

MapとListに保存したい値を設定して、復元するときにそこから取り出す感じになります。もちろん保存する値は Bundle に保存できる値ではないとクラッシュします。

参考

https://developer.android.com/jetpack/compose/state#restore-ui-state

--

--

Kenji Abe
Kenji Abe

Written by Kenji Abe

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

No responses yet