Implement ViewModelProvider.Factory Interface for Custom ViewModel / AndroidViewModel Factory Creation
We do NOT need to extend ViewModelProvider.NewInstanceFactory (for ViewModel) or ViewModelProvider.AndroidViewModel (for AndroidViewModel)
In my previous post - Recommended Ways To Create ViewModel or AndroidViewModel, I mentioned that in order to create ViewModel
, we need to create a factory that extends ViewModelProvider.NewInstanceFactory()
and to create AndroidViewModel
, we need to extend ViewModelProvider.AndroidViewModelFactory()
.
Well, it works, but it is unnecessary. We can just implement the ViewModelPrvoider.Factory
interface directly for both of them.
ViewModelProvider.NewInstanceFactory()
class MyViewModelFactory(private val repository: Repository)
: ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
return MyViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Can be replaced by ViewModelProvider.Factory
class MyViewModelFactory(private val repository: Repository)
: ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
return MyViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
ViewModelProvider.AndroidViewModelFactory(app)
class MyAndroidViewModelFactory(
private val app: Application,
private val repository: Repository)
: ViewModelProvider.AndroidViewModelFactory(app) {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(
MyAndroidViewModel::class.java)) {
return MyAndroidViewModel(app, repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Can be replaced by ViewModelProvider.Factory
class MyAndroidViewModelFactory(
private val app: Application,
private val repository: Repository)
: ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(
MyAndroidViewModel::class.java)) {
return MyAndroidViewModel(app, repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Since both ViewModelProvider.NewInstanceFactory()
and ViewModelProvider.AndroidViewModelFactory()
implementViewModelPrvoider.Factory
interface, we can just implement the ViewModelPrvoider.Factory
interface directly to create the custom ViewModel
/ AndroidViewModel
factory which takes in different constructor parameters. We don't need an additional layer here.
By the way, this is the feedback that I get from medium suggesting another better approach is to use Hilt Dependency Injection instead of using factory to create the custom ViewModel
, which is also known as constructor dependency injection.
I personally have not used Hilt yet, and will definitely learn and blog about it.
[Updated - July 04, 2022]: I have played around with Hilt a bit and here are the simple steps to implement Hilt into your app.