見出し画像

[Android] ViewModel-SavedState-ktx 2.2.0 をリリースしました

# ViewModel-SavedState-ktx とは

ViewModel-SavedState の SavedStateHandle を Delegated Property で簡単に扱えるようにするライブラリです。

# ViewModel-SavedState とは

これまで、UI の状態は onSavedInstanceState で保存され、onCreateで復元されていました。今後、ViewModel-SavedState を使って SavedStateHandleで UI の状態を保存・復元できます。

# なぜ ViewModel-SavedState を使うのか

画面回転などの Configuration Changes が発生した場合、ViewModel は生き続けますが、メモリ不足により OS によって Activity が強制終了されると、ViewModel は破棄されます。 ViewModel-SavedState を使用すると、Activity がOSによって強制終了されたときに ViewModel のプロパティを保存できます。

# ViewModel-SavedState の使い方

## SavedStateHandle の取得方法

ViewModel のコンストラクタ引数で SavedStateHandle を取得できます。

## SavedStateHandle を ViewModel のコンストラクタに渡す方法

Activity または Fragment で `by viewModels()` などを使った場合、自動的に SavedStateHandle が渡されます。ViewModel のコンストラクタ引数が `SavedStateHandle` または `Application, SavedStateHandle` 以外の場合、`by viewModels` に AbstractSavedStateViewModelFactory を継承したファクトリを渡す必要があります。

※ `by viewModels()` を使った場合、`intent.extras` または `arguments` が自動的に渡されていて SavedStateHandle を介してパラメータを受け取ることができます。ファクトリを渡した場合は、必要ならファクトリのコンストラクタに `intent.extras` または `arguments` を渡す必要があります。

## SavedStateHandle の使い方

`SavedStateHandle#get(key)` で値を取得、`SavedStateHandle#set(key, value)` で値を保存できます。値は `intent.extras` または `arguments` で初期化されています。

`SavedStateHandle#getLiveData(key)` で LiveData で値を取得可能です。`SavedStateHandle#getLiveData(key, initialValue)` で初期値を設定することも可能です。LiveData の値を変更した場合は、自動的に SavedStateHandle の値も変更されます。

# ViewModel-SavedState の問題

`SavedStateHandle#get(key)` で値を取得した場合、値を変更した時は `SavedStateHandle#set(key, value)` も呼ぶ必要があります。

SavedStateHandle の使用に key が必要です。また、その key は `intent.extras` または `arguments` のキーと同じキーを使う必要があります。

SavedStateHandle に保存できる型には制限があります。

# ViewModel-SavedState-ktx による解決

Delegated Property で値を変更したら自動的に `SavedStateHandle#set(key, value)` を呼び出します。

SavedStateHandle の使用には key は不要です。代わりにプロパティ名を使用します。Intent と Bundle にプロパティ名を key に指定するための拡張関数を提供しています。

SavedStateHandle に保存できる型と実際に ViewModel で利用する型を相互変換する SavedStateAdapter を使って任意の型を利用できます。

# ViewModel-SavedState-ktx の使い方

プロパティ参照を使った拡張関数で Intent や Bundle にパラメータを渡します。

class SampleActivity : AppCompatActivity(R.layout.sample_activity) {
   private val viewModel: SampleViewModel by viewModels()

   companion object {
       @JvmStatic
       fun createIntent(context: Context): Intent = Intent(context, SampleActivity::class.java).also {
           it.putExtra(SampleViewModel::text, "sample")
       }
   }
}

SavedStateHandle の拡張関数を Delegated Property で使い、値や LiveData を取得できます。初期値の設定や SavedStateAdapter で任意の型変換ができます。

class SampleViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
   val text: String by savedStateHandle.property()
   val count: MutableLiveData<Int> by savedStateHandle.liveData(initialValue = 0)
   val timeUnit: MutableLiveData<TimeUnit?> by savedStateHandle.liveData(object : SavedStateAdapter<TimeUnit?, Int?> {
       override fun toSavedState(value: TimeUnit?): Int? = value?.ordinal
       override fun fromSavedState(state: Int?): TimeUnit? = state?.let { TimeUnit.values()[it] }
   })
}

# ViewModel-SavedState-ktx 2.2.0 はこちら




この記事が気に入ったらサポートをしてみませんか?