I need to pass value when the view model is created (userData), so I need to create a view model factory
here is my viewModel, I need application
and userData
to init this ScoreViewModel
class ScoreViewModel(application: Application, userData: UserKM) : AndroidViewModel(application) {
}
but now I am confused how to pass application
when I create viewModel factory
class ScoreViewModelFactory(private val userData: UserKM) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ScoreViewModel::class.java)) {
return ScoreViewModel(userData = userData,application = ?????? ) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
what should I do ?
The factory is responsible to create your instance of ViewModel. If your ViewModel has dependencies and you want to test your ViewModel then you should create your own ViewModelProvider. Factory and passed dependency through ViewModel constructor and give value to the ViewModelProvider.
Creating a ViewModel instance in your activityViewModelProvider is a utility class for ViewModelStore . It internally refers to ViewModelStore to return an existing instance of the ViewModel if it exists — otherwise, it creates a new one. ViewModelStore internally keeps track of the ViewModel s using a HashMap .
You can have something like this :
class Factory(val app: Application) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(NewsViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return NewsViewModel(app) as T
}
throw IllegalArgumentException("Unable to construct viewmodel")
}
}
In your activity or fragment you have :
/**
* One way to delay creation of the viewModel until an appropriate lifecycle method is to use
* lazy. This requires that viewModel not be referenced before onActivityCreated, which we
* do in this Fragment.
*/
private val viewModel: NewsViewModel by lazy {
val activity = requireNotNull(this.activity) {
"You can only access the viewModel after onActivityCreated()"
}
ViewModelProviders.of(this, NewsViewModel.Factory(activity.application))
.get(NewsViewModel::class.java)
}
And here your viewModel can look like :
class NewsViewModel(application: Application) : AndroidViewModel(application)
For more detail you can look at : https://github.com/Ali-Rezaei/News-Cache/blob/master/app/src/main/java/com/sample/android/news/viewmodels/NewsViewModel.kt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With