Reputation: 51
When using Room database with ViewModel and LiveDate based on this codelab in order to use queries with parameter I didn't find any solution so I tried to create another constructor for both view model class and repository class but I noticed that in CodeLab they don't use view model constructors at all and instead they use view model provider so I changed it and used
new StoryViewModel(getApplication(),"Fiction");
instead of
new ViewModelProvider(this).get(StoryViewModel.class);
I don't know if there's anything wrong with this or not.
It works fine now, but if it's the way why don't we use this always?
And why do we use view model provider?
If what I did is wrong then how can I retrieve data from db based on parameters?
Thank you.
Upvotes: 4
Views: 5433
Reputation: 6805
Here is a complete example, built with knowledge I gained from Pierluigi's answer:
class MyFragment: Fragment() {
private lateinit var viewModel: ContactViewModel
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
activity?.let { activity ->
viewModel = ViewModelProvider(
activity,
MyViewModelFactory(
"mode value",
"nickname value"
)
).get(MyViewModel::class.java)
} ?: throw AssertionError("Unable to get parent activity from fragment")
}
}
class MyViewModelFactory(val mode: String, val nickname: String) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T =
modelClass.getConstructor(String::class.java, String::class.java)
.newInstance(mode, nickname)
}
class MyViewModel(val mode: String, val nickname: String) : ViewModel()
Upvotes: 1
Reputation: 495
you should not use directly viewModel constructor because the system creates the viewModel or gets it from cache. If you want to pass parameter to the viewModel constructor you should use a viewModel factory like this:
class ViewModelFactory(params) : ViewModelProviders.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return modelClass.getConstructor(params::class.java).newInstance(params);
}
}
...
override fun onCreate(...) {
viewModel = ViewModelProviders.of(this, ViewModelFactory(params)).get(MyViewModel::class.java)s
}
Upvotes: 3