MVVM(架构)
使用 DataBinding 的语法怪癖
将 viewModel 函数绑定到 xml 中的属性时,会丢弃某些函数前缀,如 get
或 is
。例如。当将它绑定到 xml 中的属性时,ViewModel 上的 ViewModel::getFormattedText
将成为 @{viewModel.formattedText}
。与 ViewModel::isContentVisible
类似 - > @{viewModel.contentVisible}
(Java Bean 表示法)
生成的绑定类如 ActivityMainBinding
以它们为其创建绑定的 xml 而不是 java 类命名。
自定义绑定
在 activity_main.xml 中,我在 app
上设置了 textColor 属性,而不是 android
命名空间。这是为什么?因为有一个为属性 textColor
定义的自定义 setter,它解析了一个 ColorRes 资源 id,由 ViewModel 发送到实际颜色。
public class CustomBindings {
@TargetApi(23)
@BindingAdapter({"bind:textColor"})
public static void setTextColor(TextView textView, int colorResId) {
final Context context = textView.getContext();
final Resources resources = context.getResources();
final int apiVersion = Build.VERSION.SDK_INT;
int color;
if (apiVersion >= Build.VERSION_CODES.M) {
color = resources.getColor(colorResId, context.getTheme());
} else {
color = resources.getColor(colorResId);
}
textView.setTextColor(color);
}
}
有关其工作原理的详细信息,请检查 DataBinding Library:Custom Setters
等等……你的 xml 中有逻辑!!!?
你可以说我在 xml 中为 android:visibility
和 app:textColor
做的事情是 MVVM 上下文中的错误/反模式,因为我的视图中有视图逻辑。但是我认为,出于测试原因,让我的 ViewModel 保留 Android 依赖项更为重要。
此外,app:textColor
究竟做了什么?它只解析一个指向与之关联的实际颜色的 ressource 指针。因此 ViewModel 仍然根据某些条件决定显示哪种颜色。
至于 android:visibility
,我觉得因为方法的命名方式,实际上可以在这里使用三元运算符。由于名称 isLoadingVisible
和 isContentVisible
,在视图中每个结果应该解决的问题确实毫无疑问。所以我觉得它实际上是执行 ViewModel 给出的命令,而不是真正做视图逻辑。
另一方面,我同意使用 viewModel.isLoading ? View.VISIBLE : View.GONE
将是一件坏事,因为你在视图中假设该状态对于视图意味着什么。
有用的材料
以下资源帮助我了解了这个概念:
- Jeremy Likness - 模型 - 视图 - 视图模型(MVVM)解释 (C#)(08.2010)
- Shamlia Shukkur - 了解 MVVM 设计模式的基础知识 (C#)(03.2013)
- Frode Nilsen - Android 数据绑定:Goodbye Presenter,Hello ViewModel! (07.2015)
- Joe Birch - 使用 MVVM 接近 Android (09.2015)
- Florina Muntenescu - Android 架构模式第 3 部分:模型 - 视图 - ViewModel (10.2016)