Android DataBinding (四) 自定義屬性
前言
DataBinding 的時候,會呼叫 View 的,setXxx 方法。比如下面程式碼
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}" />
繫結的時候,會呼叫 setText(String text) 方法。
前提是 TextView 已經有了 setText(String text) 方法,沒有 setText 方法,或者 setText 方法的方法簽名不一樣,都是不行的。
所以,不是所有的屬性都能通過 DataBinding 來設定。
當沒有方法的時候,有兩種做法
1. 如果有類似的方法,只是方法名或者方法簽名不一樣,可以通過設定來呼叫現有的方法。
比如 android:onClick,View 中沒有 setOnClick 方法,但是有 setOnClickListener 方法,而且方法簽名是一樣的。
這時候我們可以使用 BindingMethod 來做箇中轉。
@BindingMethods({
@BindingMethod(type = View.class, attribute = "android:onClick", method = "setOnClickListener")
})
@BindingMethods 定義到類名上面。
當然,如果你僅僅是想重新命名 setter,也可以通過 @BindingMethods 來實現。
比如 android:paddingLeft,View 中是沒有 setPaddingLeft 方法的,只有 setPadding 方法。
這時候可以自定義一個 set 方法,並在方法上面新增 @BindingAdapter。
@BindingAdapter("android:paddingLeft")
public static void setPaddingLeft(View view, int padding) {
view.setPadding(padding,
view.getPaddingTop(),
view.getPaddingRight(),
view.getPaddingBottom());
}
2. 沒有類似方法,新增對應的方法。
比如 app:xxx 屬性
如果方法簽名就是 app:xxx 屬性裡設定的值得話,直接定義 setXxx 方法即可。
如果方法簽名像上面的 setPaddingLeft 一樣,還需要把 View 自己也傳入的話,那麼除了要定義 setXxx 方法,還需要新增 @BindingAdapter(“android:xxx”)
DataBinding Library 提供了一些自定義屬性
幸運的是,有些常用的屬性,比如上面提到的 android:onClick 和 android:paddingLeft,Library 已經幫你設定好了,自己不需要在設定就可以直接使用了。(具體可以參照android.databinding.adapters.ViewBindingAdapter)
多屬性繫結
同一個方法,可以同時設定多個屬性
@BindingAdapter({"bind:imageUrl", "bind:error"})
public static void loadImage(ImageView view, String url, Drawable error) {
Picasso.with(view.getContext()).load(url).error(error).into(view);
}
Picasso 讀取圖片同時需要 imageUrl 和 error。同時定義的時候才呼叫,缺一不可。
上面的例子是同時設定的時候才呼叫,如果是定義了其中某一個的時候就呼叫的話,只需要加個 requireAll = false 就 OK 了。
@BindingAdapter(value = {"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"},
requireAll = false)
public static void setOnAttachStateChangeListener(View view,
final OnViewDetachedFromWindow detach, final OnViewAttachedToWindow attach) {
}
setOnAttachStateChangeListener 在 android:onViewDetachedFromWindow 或者 android:onViewAttachedToWindow 其中之一呼叫的時候就呼叫。