Android MVVM UI 控件

Posted

技术标签:

【中文标题】Android MVVM UI 控件【英文标题】:Android MVVM UI control 【发布时间】:2020-11-26 11:35:11 【问题描述】:

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

假设我有一个基本的用户界面,例如一个表单。它有几个 EditTextViews 来输入数据。最后它还有一个开关。如果它是ON,则会显示更多的 EditTextViews 来填充。当它OFF时,它们当然消失了。

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

    在活动/片段代码中?然后业务逻辑将涉及到 MVVM 的 VIEW 部分(我觉得不太好)。

    在视图模型中?然后业务逻辑将存在于一个,比如说,数据缓存中。这样我就必须在 ViewModel 中创建一堆 boolean getter 来计算单独视图可见性的值。然后在我的 Activity 中的 LiveData 更改订阅块中,我需要读取所有这些值并一一设置视图的可见性。

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

这里的最佳做法是什么?不过,同样的问题可以提出用户输入验证的主题(我猜这些领域有很多)。

【问题讨论】:

开/关状态是否会影响 UI 可见性以外的其他内容?如果没有 UI,它在业务逻辑中的作用是什么? 当它打开时,业务逻辑分别填充 POJO 中的字段,当它关闭时,相同的字段将被留空/清除。例如,如果Under Age开关打开,用户必须输入法定代表人的数据(母亲姓名等),这些数据需要保存。 按照我的理解,它是由 UI(用户单击按钮)驱动的,而不是从其他 POJO 属性派生的,例如出生日期VS现在?如果用户打开按钮,填写字段并将其关闭,POJO 应该有空值,无论 UI 中的字段不是空的,对吗? 正确。是的,我现在知道这个例子不是最好的。如您所述,在大多数用例中,必须从出生日期和当前日期计算未成年人。这只是一个场景的快速示例,有时需要显示一些 UI 组件,有时需要消失。 【参考方案1】:

我会采用第二种方法,但实施方式略有不同(使用 DataBinding),灵感来自 Google 的示例 Sunflower 应用程序: https://github.com/android/sunflower 它应该引入 Jetpack 最佳实践,包括 MVVM。

然后,在我的 Activity 中的 LiveData 更改订阅块中,我需要读取所有这些值并一一设置视图的可见性。

您可以将布局订阅到视图模型(使用 DataBinding),而不是这样做,类似于:https://github.com/android/sunflower/blob/master/app/src/main/res/layout/fragment_plant_detail.xml

    <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"

【讨论】:

老实说,如果可能的话,我会避免使用 DataBinding。我有两个原因: - 就像我在原始问题的#1 选项中所说的那样,这会将业务逻辑放入应用程序的 VIEW 层。 - 当您将代码写入string 并让后台架构将其作为代码执行时,我通常不热衷于解决方案。如果一切看起来都正常(没有错别字、编译问题等),那么正确的功能就会发生。我会尽量避免,这真的不符合我对源代码的品味。 阅读这篇文章,了解为什么它很危险:medium.com/@hellotimmutton/… 我以前读过它,虽然我同意关注点分离的重要性,但我不同意他的解释。该模型应该与附加到它的任何 UI 一起使用,例如android:visibility=”@viewModel.showTitle ? View.VISIBLE : View.GONE” 是一个不好的例子——它描述的是 UI 状态,而不是业务逻辑状态。如果在业务逻辑中存在您不希望显示标题的状态,则添加反映该状态的可观察对象,并让 UI 对其做出反应(例如,通过隐藏标题,也许还有其他一些视图 - 这就是我要做的在片段中或与数据绑定) 我将使用我们讨论过的#2 方法,但尝试使用 LiveData。

以上是关于Android MVVM UI 控件的主要内容,如果未能解决你的问题,请参考以下文章

如何构建Android MVVM 应用框架

Android MVVM框架使用(十三)UI更新 (App启动白屏优化适配Android10.0深色模式)

如何构建Android MVVM 应用框架

安卓studio 怎么搭建mvvm

如何构建Android MVVM应用程序

android ui控件都有哪些