Somebody wrote two extension function (Code A2) for both Fragment
and FragmentActivity
to instantiate a ViewModel
, it works well, you can see Code A1 and Code A3.
I hope to write two extension function (Code B2) for both Fragment
and FragmentActivity
to instantiate a AndroidViewModel
, you can see Code B1 and Code B3, how can I do? Thanks!
Code A1
class HomeViewModel_A(private val mDBVoiceRepository: DBVoiceRepository) : ViewModel() {
}
Code A2
inline fun <reified T : ViewModel> Fragment.getViewModel(noinline creator: (() -> T)? = null): T {
return if (creator == null)
ViewModelProvider(this).get(T::class.java)
else
ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}
inline fun <reified T : ViewModel> FragmentActivity.getViewModel(noinline creator: (() -> T)? = null): T {
return if (creator == null)
ViewModelProvider(this).get(T::class.java)
else
ViewModelProvider(this, BaseViewModelFactory(creator)).get(T::class.java)
}
Code A3
class FragmentHome : Fragment() {
private val mHomeViewModel_A by lazy {
getViewModel {
HomeViewModel_A(provideRepository(mContext))
}
}
}
Code B1
class HomeViewModel_B(application: Application,private val mDBVoiceRepository: DBVoiceRepository) : AndroidViewModel(application) {
}
Code B2
?
Code B3
class FragmentHome : Fragment() {
private val mHomeViewModel_B by lazy {
?
}
}
The Ktx Fragments library already has a function for concisely creating a lazy delegate to retrieve a view model:
Fragment.viewModels()
andFragmentActivity.viewModels()
.These work for both ViewModel and AndroidViewModels with the default constructors (empty, or an Application parameter respectively), or you can use the trailing lambda to return a view model factory. You would use it like this:
or
To get something equivalent to what you have in A2, you can wrap this function to have it build a factory for you: