1. 程式人生 > >Android DataBinding (四) 自定義屬性

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 其中之一呼叫的時候就呼叫。