♻️

ViewModelに非NavigationクラスからSavedStateHandleを渡す

に公開

以下のようなViewModelがある。

class SampleViewModel(
    savedStateHandle: SavedStateHandle,
) : ViewModel() {

    init {
        val id = savedStateHandle.get<String>("sampleKey")
        ...
    }

}

Navigationを利用する場合は、自動的にSavedStateHandleにNavigationのパラメータを入れてくれるようになっている。
これのViewModelを非Navigationの画面からも使いたい場合、以下のようにすれば良い。


val viewModel: SampleViewModel by viewModels(
  extrasProducer = {
    MutableCreationExtras().apply {
      set(DEFAULT_ARGS_KEY, bundleOf("sampleKey" to "sampleId")
    }
  }
)

なお、デフォルトではSavedStateHandleには、ActivityであればIntentのExtras、Fragmentであればargumentsが入るようになっている。
上記の書き方をしてしまうとそれが失われてしまうので、もしそれも使いたい場合は下記のように書くと両方使うことが出来る。


val viewModel: SampleViewModel by viewModels(
  extrasProducer = {
    MutableCreationExtras(defaultViewModelCreationExtras).also {
      it[DEFAULT_ARGS_KEY]?.apply {
        putString("sampleKey", "sampleId")
    }
  }
)

defaultViewModelCreationExtrasにDEFAULT_ARGS_KEYをキーとしてExtrasやargumentsがBundleとして入っているので、それを取得してputすれば良い。

Discussion