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)