之前 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);
}
}
}