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
を実装することで対応することもできます。
Saver
は Bundle
に保存できる型に変換して、Bundle
から復元した値を変換する処理を実装します。 実装したものをrememberSaveable
の saver
パラメータに渡すことで対応できます。
MutableState
を使う場合は stateSaver
パラメータのほうに実装した Saver
を渡します。
補足ですが、 パラメータを指定しなかった場合はデフォルトの AutoSaver
が使用されます。
mapSaver と listSaver
Saver
を実装するためのヘルパーメソッドとして、 mapSaver
と listSaver
が用意されています。
実装としては以下のような感じになります。
MapとListに保存したい値を設定して、復元するときにそこから取り出す感じになります。もちろん保存する値は Bundle
に保存できる値ではないとクラッシュします。
参考
https://developer.android.com/jetpack/compose/state#restore-ui-state