【发布时间】:2017-10-24 01:43:41
【问题描述】:
关于带有新架构组件的 MVVM,我有一个问题,如果我的应用程序需要显示例如一个对话框,其中包含来自我的 VM 中发生的某些操作的 3 个选项,我应该如何实现?谁负责向 Activity/Fragment 发送显示对话框的命令?
【问题讨论】:
标签: android mvvm architecture components presenter
关于带有新架构组件的 MVVM,我有一个问题,如果我的应用程序需要显示例如一个对话框,其中包含来自我的 VM 中发生的某些操作的 3 个选项,我应该如何实现?谁负责向 Activity/Fragment 发送显示对话框的命令?
【问题讨论】:
标签: android mvvm architecture components presenter
在对话框中:
val viewModel =
ViewModelProvider(context as ViewModelStoreOwner)[MyViewModel::class.java]
viewModel.sendUserAnswer()
【讨论】:
在 Android 中,最常见的从 ViewModel 到视图(Activity/Fragment)的通信是通过观察 LiveData 值。在 ViewModel 中设置 MutableLiveData 值并将其作为 LiveData 暴露给视图以进行观察。 这在对某些状态变化做出反应时很方便。设置状态持续存在并且相关,直到下一次更改。例如在配置更改时很方便,我们的视图状态保存在 ViewModel 中。
但有时这是不可取的 - 使用“简短”或“无状态”操作 - 它们只会短暂更改 UI 的状态并且仅在操作发生时相关 - 例如显示消息的操作(无论是吐司或小吃店)——我们不想因为屏幕旋转而在 10 分钟后重新显示错误消息;或导航操作 - 我们不想在顶部重新打开另一个屏幕。这些可以通过 Jose Alcé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"
【讨论】:
与 UI 相关的操作(例如打开新活动或显示对话框)是从视图(活动或片段)触发的,而不是从 ViewModel 触发的。 ViewModel 没有对视图的引用以防止泄漏并保持表示层“反应性”。
您可以将您的视图(活动或片段)订阅到 ViewModel 中的可观察对象,以便当它发生更改时,您可以从视图启动对话框或新活动。
编辑:我写了一篇关于这个的文章,因为它并不简单。一个好的方法是将事件建模为状态的一部分,并使用事件包装器进行导航等操作:https://medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the-singleliveevent-case-ac2622673150
【讨论】: