android - MVVM:根据用例使用不同的 ViewModel 实现
问题描述
我有一个应该在多个用例中重用的片段,例如称为AddOrEditRecipeFragment
,这个片段可用于创建或编辑配方,因为无论您创建或编辑配方,它都是相同的 UI。
但我想使用一个AddReceipeViewModel
或EditRecipeViewModel
实例,具体取决于用例,它由片段上的 FragmentArgument 标识。两者都AddReceipeViewModel
实现EditRecipeViewModel
了相同的接口,所以我目前做的是:
private val viewModel: MyViewModelInterface by lazy {
val mode = // ... just get a flag from the arguments which indicates which mode we are in
val vm: MyViewModelInterface = when(mode) {
Mode.EDIT -> { val vm: EditRecipeViewModel by activityViewModel(); vm }
Mode.ADD -> { val vm: AddRecipeViewModel by activityViewModel(); vm }
vm
}
这感觉非常错误,因为片段知道需要知道所有可能的实现MyViewModelInterface
。有谁知道对此有更好的解决方案?
谢谢
解决方案
您可以创建一个factory
并将模式传递给工厂,让逻辑决定要实例化哪个视图模型,factory
因此片段仅取决于接口。
在你的片段中添加这个
private val factory = ViewModelFactory() // inject it instead if using DI
private val viewModel: MyVieModelInterface by activityViewModels {
factory
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val mode = // get mode from arguments
factory.mode = mode
}
和
abstract class MyVieModelInterface : ViewModel() /* rename as it's not an interface */ {
}
class ViewModelFactory : ViewModelProvider.Factory {
lateinit var mode: Mode
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T = if (modelClass.isAssignableFrom(MyVieModelInterface::class.java)) {
when (mode) {
Mode.EDIT -> EditViewModel(/* stuff here */)
Mode.ADD -> AddViewModel(/* stuff here */)
}
} else {
throw IllegalArgumentException("Unknown ViewModel class [$modelClass]")
}
}
推荐阅读
- javascript - 有没有办法通过只提取某些值来减少嵌套的 json?
- java - Java中的无符号模数
- algorithm - 激光雷达:如何根据初始地图扫描确定运动/对象?
- c# - 如果公里超过 100 公里,每公里额外支付 0.20 美分
- c++ - 使用 MSXML6 访问 XML 结构中的属性值 - C++
- maven - 如何让 JavaFx WebEngine 详细报错?
- java - 如何在 Java 中访问另一个文件或类上的 JButton
- python - Can someone please explain me these lines of code?
- python-3.x - Discord.py on_invite_create event
- javascript - Rectangle not showing on canvas