やりたいこと
こんな感じで、ラベルの横に入力必須の *
マークをつけたい場合、要素がたくさんあると地味にめんどくさいです。
BindingAdapterを使う
BindingAdapterを使えばxmlのattributesで書けます。
DataBindingはkotlinの拡張関数のようなもので、既存のViewに動きを付与できます。
適当なクラスに下記のようなstaticメソッドを書いておきます。自分は DataBindingAttributeUtil
を作ってそこに置きました。
@BindingAdapter("requiredMarkVisible")
public static void requiredMarkVisible(TextView textView, boolean enable) {
String text = textView.getText().toString();
String requiredMark = " " + textView.getContext().getString(R.string.required_mark);
if (enable) {
textView.setText(Html.fromHtml(text + "<font color=\"#e86242\">" + requiredMark + "</font>"));
} else {
String defaultText = text.replace(requiredMark, "");
textView.setText(defaultText);
}
}
xmlではでこんな感じで書けます。 @{true}
じゃなくてtrue
で書きたいですが、何かいい方法があるんでしょうか。あれば知りたいです。
<TextView
...
android:text="@string/name"
app:requiredMarkVisible="@{true}"/>
補足
ちなみに、なぜ false
の時にわざわざ text.replace(requiredMark, "")
としているかというと、状態によって必須かどうかが動的に変わるケースがあるからです。
例えば以下のようにViewModelの状態が変わったらrequiredMarkVisible
も変更してほしいみたいな時のためです。
<TextView
...
android:text="@string/name"
app:requiredMarkVisible="@{viewModel.isNameRequired}"/>
所感
もしかしたらstringの%1$s
とかをxml上でセットできるような、汎用的なBindingAdapterを作った方がいいのかもしれないです。そのうち試してみます。
以上です。