###使用记录和注意项
- Databinding的插件对AS的支持还是有些缺陷,有时候ViewDataBinding读取不到variable的setter,
去build->generated->source->apt->debug-><包名>->databinding
目录下查找对应方法。如果存在,那可能只是AS的误报。 - @BindingAdapter注解需要修饰静态(static)方法,不需要设置到viewdatabinding中,apt会自动查找并转换。具体实现可以在对应的viewDataBinding类的
executeBindings
方法中找到。 - 在xml的使用相关的工具类或者方法,需要在
<data>
中引用对应的类(包括R文件)。eg:<import type="android.view.View"/>
隐式属性引用
<CheckBox android:id="@+id/cb_Test" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="选中" /> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:text="选中显示" android:gravity="center" android:visibility="@{cbTest.checked?View.VISIBLE:View.GONE}" />
CheckBox的id是cb_Test,而引用的变量时cbTest,变量名称使用是根据ViewDatabinding的属性名称,而非XML中的ID.
5.反向绑定
- @InverseBindingMethod
public @interface InverseBindingMethod {
/**
* The View type that is associated with the attribute.
*/
Class type();
/**
* The attribute that supports two-way binding.
*/
String attribute();
/**
* The event used to notify the data binding system that the attribute value has changed.
* Defaults to attribute() + "AttrChanged"
*/
String event() default "";
/**
* The getter method to retrieve the attribute value from the View. The default is
* the bean method name based on the attribute name.
*/
String method() default "";
}
- event()和method()如果为空,都会默认采用attribute的标准命名格式
- event:attribute() + "AttrChanged" :触发数据更新的事件
- method:get+attribute() 或者 is+attribute() :获取数据值的方法
定义反向绑定完成后,需要设置触发反向绑定的方法,通常采用@BindingAdapter(value = {event()的值}, requireAll = false)注册一个参数变化监听方法。
例如TextView的文本修改监听:
@BindingAdapter(value = {"android:beforeTextChanged", "android:onTextChanged",
"android:afterTextChanged", "android:textAttrChanged"}, requireAll = false)
public static void setTextWatcher(TextView view, final BeforeTextChanged before,
final OnTextChanged on, final AfterTextChanged after,
final InverseBindingListener textAttrChanged) {
final TextWatcher newValue;
if (before == null && after == null && on == null && textAttrChanged == null) {
newValue = null;
} else {
newValue = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (before != null) {
before.beforeTextChanged(s, start, count, after);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (on != null) {
on.onTextChanged(s, start, before, count);
}
if (textAttrChanged != null) { //这里是重点
textAttrChanged.onChange();
}
}
@Override
public void afterTextChanged(Editable s) {
if (after != null) {
after.afterTextChanged(s);
}
}
};
}
final TextWatcher oldValue = ListenerUtil.trackListener(view, newValue, R.id.textWatcher);
if (oldValue != null) {
view.removeTextChangedListener(oldValue);
}
if (newValue != null) {
view.addTextChangedListener(newValue);
}
}
这个方法监听4个xml属性:
1. android:beforeTextChanged
2. android:onTextChanged
3. android:afterTextChanged
4. android:textAttrChanged
反向绑定主要需要android:textAttrChanged即InverseBindingListener监听器。该监听器会在当前的ViewDataBinding类中自动添加,作为反向刷新的回调。
**用通俗点的话说,我们需要在EditText的录入事件里面修改数据源的值,那么我们就需要在EditText的输入事件里添加数据源刷新回调。**
至于其他三个属性对应着监听器**TextWatcher**的三个方法,可以在xml里面赋值,否则传null
额外补充点:
1)其他三个属性的赋值例子代码:
xml:
<EditText
android:id="@+id/etText"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="@={viewHolder.mEditTest}"
android:onTextChanged="@{viewHolder.changed}"
android:gravity="center"
/>
viewHolder类中:
public TextViewBindingAdapter.OnTextChanged changed = new TextViewBindingAdapter.OnTextChanged() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.e("url","changed");
}
};
2)该setTextWatcher事件在executeBindings()中已经完成,不会覆盖activity中的TextWatcher事件
@InverseBindingAdapter(用于重新实现UI返回值给数据源的getter方法,实现这个就不需要@InverseBindingMethod了)
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged") public static String getTextString(TextView view) { return view.getText().toString(); }
- attribute:对应双向绑定的属性,eg: android:text或者app:refresh
- event:触发数据更新的事件,与上面的@BindingAdapter关联(关联点:android:textAttrChanged)
END
–Nowy
–2018.10.22