我看过很多教程,但并没有真正使自己正确理解如何处理MVVM中的某些情况。
假设有一个存储库,该存储库从使用DAO
的{{1}}中获取数据
Room
查询存储库的ViewModel
class Repository(){
fun getItems() = itemsDAO.getItems()
}
还有一个片段
class FragmentViewModel:ViewModel(){
val items = repository.getItems()
fun updateItem(Item item){
repository.updateImte(itemm)
}
}
这是我从教程中了解的方法。基本上,我需要澄清一些事情,我想寻求您的帮助。
a。考虑到class MyFragment:Fragment(){
//onViewCreated
viewModel.items.observe(...){
//if result, update the views
}
buttonUpdateItem.setOnClickListener{
viewModel.updateItem(Item item)
}
}
的这种实现方式,如果用户旋转设备并重新创建了片段,这是否意味着添加ViewModel
时将再次查询数据库?
我正在考虑更新ViewModel之类的
observe
如果我是对的,这应该允许从db返回初始值,并且在片段重新创建的情况下不要再次调用db。
b。 class FragmentViewModel:ViewModel(){
private final var itemsObservable;
init {
itemsObservable = repository.getItems()
}
fun items(){
return itemsObservable
}
fun updateItem(Item item){
repository.updateImte(item)
}
}
应该如何对ViewModel
采取行动,更准确地说是单击按钮事件?应该像上面的示例中的Fragment
那样调用fragment
函数还是viewModel.updateItem
返回一个viewModel
变量,该变量应该设置为按钮?
c。应该将传递给onClickListener
的参数也添加到fragment
吗?
ViewModel
拥有ViewModel
的变量,因此,例如,如果我要更新项目,则LiveData<List<>>
会传递那个fragment
。这是一个好方法吗?
答案 0 :(得分:3)
首先,我想向您指出 Android Architecture Blueprints在GitHub上:
该项目的重点是演示如何构建您的 代码,设计架构,以及采用该技术的最终影响 这些模式来测试和维护您的应用。您可以使用 这里以许多不同的方式演示了构建应用程序的技术。 您自己的优先事项会影响您实施 这些项目中的概念,因此您不应该考虑这些样本 成为典型的例子。
这些是Android中不同体系结构的官方示例,您一定要检查一下以启发自己的项目。
a。更新的版本是执行此操作的正确方法-检索项目列表,一次调用存储库方法,并将返回值存储在ViewModel
中。在您的DAO中使用LiveData<List<Item>>
作为返回值,Room会自动向Observer
中的Fragment
通知您的任何更改。
b。 ViewModel
可以使用updateItem(item: Item)
方法。 onClickListener
应该放在Fragment
中。您可能还希望在调用Fragment
方法之前在updateItem
中进行一些验证。同样重要的是,不要在View
中保留任何ViewModel
引用。
要通知Fragment
有关更新状态,您可以考虑在LiveData
中有另一个ViewModel
字段(例如errorMessage: LiveData<Int>
)并将其分配给R. id
您要显示的字符串资源。这样,您就可以将确定要显示的特定消息的逻辑从Fragment
移到ViewModel
。
c。 ViewModel
中只需要一些参数。例如,当您在Fragment
的{{1}}中传递了一个id附加参数时,您将使用此id初始化Bundle
来加载该项目。
ViewModel
绝对是一个好方法。您也可以考虑创建一个Presenter来将某些逻辑从Item
中分离出来(因此它不适用于Fragment
)。您可以在上面的GitHub链接上找到更多信息和示例。
因此,我认为根据您所开发的应用程序,可以选择不同的方法。测试非常重要,在实施一种方法之后,您将发现它如何影响编写测试的难易程度。但是,这就是我如何看待您的问题的答案。