什么是BindingAdapter
绑定适配器,是 Jetpack DataBinding 中用来扩展布局 xml 属性行为的注解,允许你针对布局 xml 中的一个或多个属性进行绑定行为扩展,这个属性可以是自定义属性,也可以是原生属性。这个扩展行为可以是简单的ViewModel属性与控件赋值绑定,也可以是关联某个控件属性的额外操作,例如在设置属性之前进行值域检查,或类型转换,或者统一处理一些事情。
工作机制
BindingAdapter 是基于 APT 注解技术工作的,APT 可以在项目构建时更具相关编写规则生成特定代码完成一些指定功能的技术.
BindingAdapter 有两个属性,value 是一个 String[] ,requireAll 是一个boolean类型:
@Target(ElementType.METHOD)
public @interface BindingAdapter {
/**
* @return 与此绑定适配器相关的属性。
*/
String[] value();
/**
* 这个值默认是 true,表示使用这个适配规则必须在 XML 中声明该注解关注所有属性值,否则编译时会报错,而 false 则不需要,他允许只使用关注的部分或全部属性来使用该规则The default
* value is true.
*/
boolean requireAll() default true;
}
value 用来描述 XML 中感兴趣的关联属性,这里是个数组,说明一个扩展方法可以同时关注多个 XML 属性。这个很重要,有时候我们可能在对控件进行赋值时,需要同时给定多个值,而 XML 属性值却一次只能指定一个变量,这样可能会让我们不的不为此去扩展一个复合对象来完成这样的赋值,但是实际上并不需要那样。
requireAll 用来对 value 补充说明的,这个值默认是 true,表示使用这个适配规则必须在 XML 中声明该注解关注所有属性值,否则编译时会报错,而 false 则不需要,他允许只使用关注的部分或全部属性来使用该规则。
使用
BindingAdapter声明有固定的格式
// 类构建可以随意,APT会在构建时扫描全局代码
public class ViewAttrAdapter {
// 需要注意的是 XML标签 关注了几个,参数列表就需要写几个对应的接受参数。且关注控件类必须在第一个参数。
@BindingAdapter({xml属性标签, ...})
public static void 函数名(关注的控件类 view, xml属性标签值 value, ...){
// 行为
}
// 可以包含多个函数
.....
}
例如:
1. 我们自定义了两个BindingAdapter
:setCircleImageUrl
用来加载圆形图片,setOnClickListener
用来设置View的点击事件,同时支持设置点击背景。
public class BindingAdapters {
// 设置圆形图片
@BindingAdapter("circleImageUrl")
public static void setCircleImageUrl(ImageView view, String url) {
Glide.with(view.getContext())
.load(url)
.apply(RequestOptions.circleCropTransform())
.into(view);
}
// 设置View的点击事件
@BindingAdapter(value = {"onClick", "onClickBackground"}, requireAll = false)
public static void setOnClickListener(View view, View.OnClickListener listener, Drawable background) {
view.setOnClickListener(listener);
if (background != null) {
view.setBackground(background);
}
}
// ... 其他自定义操作
}
2. 然后,我们在XML布局文件中使用DataBinding,如下所示。
<layout>
<data>
</data>
<LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:circleImageUrl="@{`https://goss.veer.com/creative/vcg/veer/800water/veer-136599950.jpg`}"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
app:onClick="@{viewModel::onButtonClick}"
app:onClickBackground="@{@drawable/myBackground}"/>
</LinearLayout>
</layout>
上述代码中,我们通过自定义的BindingAdapter
实现了加载圆形图片、设置View的点击事件及点击背景。其中app:onClick
和app:onClickBackground
则是自定义的setOnClickListener
方法。