Android DataBinding (四) 自定義屬性

Android DataBinding (一) 基本用法
Android DataBinding (二) 事件處理
Android DataBinding (三) Observable
Android DataBinding (四) 自定義屬性 (本文)
Android DataBinding (五) 自定義 View 的雙向綁定
Android DataBinding (六) EditText 綁定 TextChangedListener 和 FocusChangeListener

前言

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,也可以通過 @BindingAdapter 來實現。

比如 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 其中之一調用的時候就調用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容