Yang
1 min readMar 4, 2018

--

Now with the new support lib 27.1.0 both Fragment and FragmentActivity implement ViewModelStoreOwner so it makes more sense to just add an extension function on `ViewModelStoreOwner` itself:

inline fun <reified T: ViewModel> ViewModelStoreOwner.getViewModel(crossinline initializer: () -> T): T {
val viewModelClass = T::class.java
val factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return when {
modelClass.isAssignableFrom(viewModelClass) -> initializer.invoke() as T
else -> throw IllegalArgumentException("Unknown ViewModel class")
}
}
}
return ViewModelProvider(this, factory).get(viewModelClass)
}

To retrieve a vew model instance:

// viewModelStoreOwner can be any Fragment or FragmentActivity
viewModel = viewModelStoreOwner.getViewModel {
SearchViewModel(param1, param2, ...)
}

Passing in an initialization block means new viewModel instance will only be created if factory thinks it’s necessary i.e. no new instance is created after rotation just to get access to the factory. I think this is a slight advantage over extending on T: ViewModel in which case you always need an instance of viewModel to access the factory.

And there’s no need to interact with ViewModelFactory with this approach.

Keen to know your thoughts :)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response