2
1

More than 1 year has passed since last update.

ViewModelでAssistedInjectをするときは拡張関数を作ると便利

Posted at

ViewModelの初期化時にFragmentから値を渡したいときにAssistedInjectを使いますが、ボイラープレートが増えてしまって非常に煩わしかったりします。そんなとき、以下のExtensionを作ると非常に便利です。

inline fun <reified T : ViewModel> Fragment.assistedViewModel(
    crossinline viewModelProducer: (SavedStateHandle) -> T
) = viewModels<T> {

    @Suppress("UNCHECKED_CAST")
    object : AbstractSavedStateViewModelFactory(this, arguments) {
        override fun <T : ViewModel> create(
            key: String,
            modelClass: Class<T>,
            handle: SavedStateHandle
        ) = viewModelProducer(handle) as T
    }
}

使い方は簡単でVewModelにFacotryを定義しつつ、上記Extensionを使ってInjectする感じです。

HogeFragment.kt
@AndroidEntryPoint
class HogeFragment : Fragment() {

    @Inject
    lateinit var factory: HogeViewModel.Factory

    private val viewModel: HogeViewModel by assistedViewModel {
        factory.create(it)
    }
}
HogeViewModel.kt
class HogeViewModel @AssistedInject constructor(
    @Assisted private val savedState: SavedStateHandle
) : ViewModel() {

    @AssistedFactory
    interface Factory {

        fun create(savedState: SavedStateHandle): HogeViewModel
    }
}

argmentsの値を渡したいときでもFactoryのcreate関数をよしなに書けばうまく動かせます。
Hilt便利!!!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1