使用 ViewModel 构造函数而不是 ViewModelProvider 能够根据参数从 Room 数据库获取数据
Using ViewModel constructor instead of ViewModelProvider to be able to get data from Room database based on parameters
当基于此 codelab 将 Room 数据库与 ViewModel 和 LiveDate 一起使用时,为了使用带参数的查询,我没有找到任何解决方案,所以 我尝试为两个视图创建另一个构造函数模型 class 和存储库 class 但我注意到在 CodeLab 他们根本不使用视图模型构造函数 而是使用视图模型供应商所以我改变了它并使用
new StoryViewModel(getApplication(),"Fiction");
而不是
new ViewModelProvider(this).get(StoryViewModel.class);
不知道这个有没有问题。
它现在工作正常,但如果是这样的话我们为什么不一直使用它呢?
并且为什么我们使用视图模型提供程序?
如果我做错了那么我如何根据参数从数据库中检索数据?
谢谢。
您不应直接使用 viewModel 构造函数,因为系统会创建 viewModel 或从缓存中获取它。如果你想将参数传递给 viewModel 构造函数,你应该使用这样的 viewModel 工厂:
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
}
这是一个完整的示例,是根据我从 Pierluigi 的回答中获得的知识构建的:
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()
当基于此 codelab 将 Room 数据库与 ViewModel 和 LiveDate 一起使用时,为了使用带参数的查询,我没有找到任何解决方案,所以 我尝试为两个视图创建另一个构造函数模型 class 和存储库 class 但我注意到在 CodeLab 他们根本不使用视图模型构造函数 而是使用视图模型供应商所以我改变了它并使用
new StoryViewModel(getApplication(),"Fiction");
而不是
new ViewModelProvider(this).get(StoryViewModel.class);
不知道这个有没有问题。
它现在工作正常,但如果是这样的话我们为什么不一直使用它呢?
并且为什么我们使用视图模型提供程序?
如果我做错了那么我如何根据参数从数据库中检索数据?
谢谢。
您不应直接使用 viewModel 构造函数,因为系统会创建 viewModel 或从缓存中获取它。如果你想将参数传递给 viewModel 构造函数,你应该使用这样的 viewModel 工厂:
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
}
这是一个完整的示例,是根据我从 Pierluigi 的回答中获得的知识构建的:
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()