关于使用新架构组件的MVVM,我有一个问题,如果我的应用程序需要显示例如一个Dialog,其中包含来自VM中发生的某些操作的3个选项,我应该如何实现?谁负责向Activity / Fragment发送显示对话框的命令?
答案 0 :(得分:32)
打开新活动或显示对话框等与UI相关的操作是从视图(活动或片段)触发的,而不是从ViewModel触发的。 ViewModel没有对视图的引用以防止泄漏并使表示层保持“被动”。
您可以将您的视图(活动或片段)订阅到ViewModel中的observable,以便在更改时,您可以从视图中启动对话框或新活动。
编辑:我写了一篇关于此的文章,因为它并不简单。一种好的方法是将事件建模为状态的一部分,并使用事件包装器执行导航等操作:https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150
答案 1 :(得分:0)
在Android中,最常见的是从ViewModel到视图的通信(活动/片段)是通过观察LiveData值来实现的。在ViewModel中设置MutableLiveData值,并将其作为LiveData公开给视图以进行观察。 当对某些状态变化做出反应时,这很方便。设置状态一直存在,并且与下一次更改相关。例如,在进行配置更改时很方便,我们的视图状态保留在ViewModel中。
但是有时这是不理想的-使用“简短”或“无状态”操作-这些操作只会短暂更改UI的状态,并且仅在操作发生时才有意义-例如显示消息的操作(烤面包或小吃店)-我们不想在10分钟后重新显示错误消息,只是因为发生了屏幕旋转;或导航操作-我们不想在顶部重新打开另一个屏幕。可以按照JoseAlcérreca的答案中所述使用SingleLiveEvent模式进行处理。
我创建了一个小型库以方便实现,用于发送此类动作-称为“简短动作”-动作,而不是事件,因为事件是我们对事件的响应以及我们发送/发起的动作。
您可以在此处查看:
https://bintray.com/vlad-markovic/maven/com.vladmarkovic.briefactions#read
它也是开源的;请随时贡献:
https://github.com/vlad-markovic/AndroidBriefActions
通过以下方式导入Gradle:
implementation "com.vladmarkovic.briefactions:briefactions:$briefActionsVersion"
答案 2 :(得分:0)
每个人都说 ViewModel 应该不包含上下文或对包含Context的类的引用。因此,从ViewModel中显示对话框不是一个好主意。 您应该从视图显示对话框,而不是从viewmodel显示对话框。