Android MVVM用户界面控件

Android MVVM用户界面控件,android,mvvm,visibility,Android,Mvvm,Visibility,我开始在Android上学习使用LiveData的MVVM。我认为显示和更新基本数据对我来说很清楚。我努力寻找最佳实践的主题是控制UI 假设我有一个基本的UI,例如一个表单。它有几个EditTextView来输入数据。最后它还有一个开关。如果它在上,则会显示更多的EditTextView来填充。当它关闭时,它们当然不见了 我的问题是在哪里实现这种逻辑 在活动/片段代码中?然后,MVVM的视图部分将涉及到业务逻辑(我觉得这不是很好) 在ViewModel中?那么,业务逻辑将存在于数据缓存中。这样

我开始在Android上学习使用LiveData的MVVM。我认为显示和更新基本数据对我来说很清楚。我努力寻找最佳实践的主题是控制UI

假设我有一个基本的UI,例如一个表单。它有几个EditTextView来输入数据。最后它还有一个开关。如果它在上,则会显示更多的EditTextView来填充。当它关闭时,它们当然不见了

我的问题是在哪里实现这种逻辑

  • 在活动/片段代码中?然后,MVVM的视图部分将涉及到业务逻辑(我觉得这不是很好)

  • 在ViewModel中?那么,业务逻辑将存在于数据缓存中。这样,我必须在ViewModel中创建一组
    boolean
    getter,用于计算单独视图可见性的值。然后,在LiveData change订阅块中的活动中,我需要读取所有这些值,并逐个设置视图的可见性

  • 在单独的服务/Helper/Util类中?这将是与#2相同的解决方案,只是从ViewModel中提取的逻辑


  • 这里的最佳实践是什么?同样的问题也会出现在用户输入验证的主题上(我想这其中有很多方面)。

    我会选择第二种方法,但略有不同的内植入(使用数据绑定),灵感来自谷歌的Sunflower示例应用程序: 它应该引入Jetpack最佳实践,包括MVVM

    然后,在LiveData change订阅块中的活动中,我需要读取所有这些值,并逐个设置视图的可见性

    与此相反,您可以将布局订阅到viewmodel(使用数据绑定),如下所示:


    开/关状态是否影响UI可见性以外的其他内容?如果没有UI,它在业务逻辑中的作用是什么?当它打开时,业务逻辑分别填充POJO中的字段,当它关闭时,相同的字段保留为空/清除。例如,如果未成年人开关打开,则用户必须输入法定代表人的数据(母亲的姓名等),并且需要保存这些数据。据我所知,这些数据是从UI(用户单击按钮)驱动的,而不是从其他POJO属性派生的,例如出生日期vs now?如果用户打开按钮,填写字段并将其关闭,POJO应该有空值,因为UI中的字段不是空的,对吗?对。是的,我现在知道这个例子不是最好的。在您提到的大多数用例中,未成年人必须从出生日期和当前日期开始计算。这只是一个场景的快速示例,有时需要显示一些UI组件,有时需要删除。老实说,如果可能的话,我会避免数据绑定。我有两个理由:-正如我在原始问题的#1选项中所说,这将把业务逻辑放入应用程序的视图层。-当您将代码写入
    字符串
    并让后台架构作为代码执行时,我通常不热衷于解决方案。如果一切正常(没有打字错误、编译问题等等),那么正确的功能就会出现。我会尽可能避免它,这确实违背了我对源代码的品味。阅读这篇关于为什么它很危险的文章:我以前读过这篇文章,虽然我同意关注点分离的重要性,但我不同意他的解释。模型应该与任何附加到它的UI一起工作,因此,例如,
    android:visibility=“@{viewModel.showttitle?View.VISIBLE:View.GONE}”
    是一个不好的例子,它描述的是UI状态,而不是业务逻辑状态。如果在业务逻辑中有一种状态,您希望不显示标题,那么添加反映该状态的可观察对象,并让UI对此做出反应(例如,通过隐藏标题,或者其他一些视图-这是我在片段或数据绑定中要做的事),我将使用我们讨论过的#2方法,但尝试使用LiveData。
        <data>
            <import type="com.google.samples.apps.sunflower.data.Plant"/>
            <variable
                name="viewModel"
                type="com.google.samples.apps.sunflower.viewmodels.PlantDetailViewModel" />
        </data>
    
    app:isGone="@{!viewModel.isUnderAge}"
    
    android:visibility="@{viewModel.isUnderAge?  View.VISIBLE : View.INVISIBLE}"