在Android MVVM架构中显示来自ViewModel的Dialog

关于使用新架构组件的MVVM,我有一个问题,如果我的应用程序需要显示例如一个Dialog,其中包含来自VM中发生的某些操作的3个选项,我应该如何实现? 谁负责向Activity / Fragment发送显示对话框的命令?

打开新活动或显示对话框等UI相关操作是从视图(活动或片段)触发的,而不是从ViewModel触发的。 ViewModel没有对视图的引用以防止泄漏并使表示层保持“被动”。

您可以将视图(活动或片段)订阅到ViewModel中的observable,以便在更改时,您可以从视图中启动对话框或新活动。

编辑:我写了一篇关于此的文章,因为它并不简单。 一种好的方法是将事件建模为您所在州的一部分,并使用事件包装器执行导航等操作: https : //medium.com/google-developers/livedata-with-snackbar-navigation-and-other-events-the- singleliveevent情况下,ac2622673150

如果通过用户输入直接触发对话框,例如单击按钮,则可以使用event参数获取对包含活动的临时引用。 因此,如果要将click事件绑定到方法,请在xml中:

  

您的viewmodel可能会包含以下内容:

 public void onClicked(View view) { MyDialogFragment.newInstance( (di, whichButton) -> doOkClicked(di, whichButton), (di, whichButton) -> doCancelClicked(di, whichButton) ).show(((Activity)view.getContext()).getFragmentManager(), "MyTag"); } public void doOkClicked(DialogInterface dialog, int whichButton) { ... } public void doCancelClicked(DialogInterface dialog, int whichButton) { ... } 

有些人可能认为这违反了MVVM原则。 只要您不维护对view参数或与之关联的上下文的引用,我不认为这是一个主要问题。 在可测试性方面,它在视图中具有可测试性(活动/片段)。 就个人而言,我喜欢在视图中保留尽可能少的代码。

更纯粹的方法可能是创建管理所有导航事件的导航服务。 我在使用MVVM Light的WPF中做过类似的事情,但Android有很大的不同,我还没有完全探索所有的问题,我相信它们有很多。