データバインディングでの文法の構文
viewModel関数をxmlのプロパティにバインドすると、 get
やis
ような特定の関数接頭辞が削除されます。例えば。 ViewModel::getFormattedText
は、xmlのプロパティにバインドするときに@{viewModel.formattedText}
になります。同様にViewModel::isContentVisible
- > @{viewModel.contentVisible}
(Java Bean表記法)
ActivityMainBinding
ような生成されたバインディングクラスは、Javaクラスではなく、バインディングを作成するXMLの名前に基づいています。
カスタムバインディング
activity_main.xmlでは、 android
名前空間ではなく、 app
textColor属性を設定しました。何故ですか? ViewModelによって実際の色に送出されるColorResリソースIDを解決するtextColor
属性用に定義されたカスタムセッターが存在するためです。
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からアンドロイド依存性を取り除くことが重要であると私は主張します。
それに、本当にapp:textColor
は何をするのですか?それは、それに関連付けられた実際の色への再ソースポインタを解決するだけです。したがって、ViewModelは、何らかの条件に基づいて表示される色を決定します。
android:visibility
については、メソッドがどのように名前付けされているかのために、ここでは三項演算子を実際に使用しても構いません。 isLoadingVisible
とisContentVisible
という名前のため、それぞれの結果がどのように解決されるべきかについて疑いはありません。だから私は実際にビューロジックを実行するよりもむしろViewModelによって与えられたコマンドを実行していると感じています。
一方、私はviewModel.isLoading ? View.VISIBLE : View.GONE
を使用することに同意するでしょうviewModel.isLoading ? View.VISIBLE : View.GONE
はビューにとってその状態の意味を前提にしているため、実行するのが悪いことです。
有用な材料
以下のリソースは、私がこのコンセプトを理解しようとするのを助けてくれました。