Android DataBinding 雙向繫結
阿新 • • 發佈:2019-01-26
之前 databinding 框架並不支援 雙向繫結,最新的版本支援了,但是用起來還算方便
以前使用的時候 是這樣繫結的
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@{checked}"
/>
現在只需要在對應的屬性 @{} 改為 @={}
想看下 具體他是那裡配置這個東西的,發現 這些都是在這個包裡面
android.databinding.adapters
然而 用checkbox 來說,這個包裡面並沒有checkbox 專用的 adapter,但是發現了這個CompoundButtonBindingAdapter,ok 應該就是這裡了
然後跟蹤到裡面發現多了兩個註解
@InverseBindingMethods({
@InverseBindingMethod(type = CompoundButton.class, attribute = "android:checked"),
})
還有方法
@BindingAdapter(value = {"android:onCheckedChanged", "android:checkedAttrChanged"},requireAll = false)
public static void setListeners(CompoundButton view, final OnCheckedChangeListener listener,
final InverseBindingListener attrChange) {
if (attrChange == null) {
view.setOnCheckedChangeListener(listener);
} else {
view.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (listener != null) {
listener.onCheckedChanged(buttonView, isChecked);
}
attrChange.onChange();
}
});
}
}
發現 多了個 android:checkedAttrChanged,這個事件繫結 這個應該是根據上面的那個 InverseBindingMethod attribute =”android:checked” 來命名的,然後方法引數也多了個 listenerfinal InverseBindingListener attrChange,
這個會在 你使用@=的時候 會注入進來。
具體的還沒試試自己寫的view 的其他屬性雙向繫結,應該自定義view 要雙向繫結屬性也需要自己寫這樣的adapter
下面是仿照 寫的一個edittext 雙向繫結
View
package com.ygsoft.testbinding;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;
/**
* Created by chenzipeng on 2016/6/22.
*/
public class AView extends EditText {
private String name;
public AView(Context context) {
super(context);
}
public AView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Adapter
package com.ygsoft.testbinding;
import android.databinding.BindingAdapter;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
import android.databinding.InverseBindingListener;
import android.databinding.InverseBindingMethod;
import android.databinding.InverseBindingMethods;
import android.databinding.adapters.ListenerUtil;
import android.text.Editable;
import android.text.TextWatcher;
/**
* Created by chenzipeng on 2016/6/22.
*/
@BindingMethods({
@BindingMethod(type = AView.class, attribute = "name", method = "setName")//定義繫結的方法
})
@InverseBindingMethods({
@InverseBindingMethod(type = AView.class, attribute = "name")//這裡有個event屬性,如果不填預設event為 attribute+"AttrChanged" ,比如這裡就是nameAttrChanged
})
public class AViewBindingAdapter {
@BindingAdapter(value = {"nameAttrChanged"}, requireAll = false)//這裡的evnet 與 @InverseBindingMethod 的event屬性相同,requireAll這裡意義不明,有可能在多個引數的時候要求所有都要注入
public static void setName(AView aView, final InverseBindingListener nameAttrChange) {
TextWatcher newWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
nameAttrChange.onChange();
}
@Override
public void afterTextChanged(Editable s) {
}
};
TextWatcher oldWatcher = ListenerUtil.trackListener(aView, newWatcher, R.id.textWatcher);
if (nameAttrChange != null) {
aView.addTextChangedListener(newWatcher);
}
if (oldWatcher != null) {
aView.removeTextChangedListener(oldWatcher);
}
}
}