Open marclee44 opened 3 years ago
BindingAdapter负责发出相应的框架调用来设置值。例如,设置属性值就像调用setText()方法一样。再比如,设置事件监听器就像调用setOnClickListener()方法。 数据绑定库允许您通过使用Adapter指定为设置值而调用的方法、提供您自己的绑定逻辑,以及指定返回对象的类型。
setText()
setOnClickListener()
设置特性值
只要绑定值发生更改,生成的绑定类就必须使用绑定表达式在视图上调用setter方法。您可以允许数据绑定库自动确定方法、显式声明方法或提供选择方法的自定义逻辑。
example
setExample(arg)
android:text="@{user.name}"
user.getName()
setText(arg)
String
int
setter
DrawerLayout
setScrimColor(int)
setDrawerListener(DrawerListener)
app:scrimColor
app:drawerListener
<android.support.v4.widget.DrawerLayout android:layout_width="wrap_content" android:layout_height="wrap_content" app:scrimColor="@{@color/scrim}" app:drawerListener="@{fragment.drawerListener}">
BindingMethods
BindingMethod
android:tint
setImageTintList(ColorStateList)
setTint()
@BindingMethods({ @BindingMethod(type = "android.widget.ImageView", attribute = "android:tint", method = "setImageTintList"), })
Glide
url
ImageView
public class ImageHelper { /** * 1.加载图片,无需手动调用此方法 * 2.使用@BindingAdapter注解设置自定义属性的名称,imageUrl就是属性的名称, * 当ImageView中使用imageUrl属性时,会自动调用loadImage方法, * * @param imageView ImageView * @param url 图片地址 */ @BindingAdapter({"imageUrl"}) public static void loadImage(ImageView imageView, String url) { Glide.with(imageView.getContext()).load(url) .placeholder(R.drawable.loading) .error(R.drawable.error) .into(imageView); } }
imageUrl就是属性的名称,当ImageView中使用imageUrl属性时,会自动调用loadImage方法,参数imageView为当前使用imageUrl属性的ImageView,参数url为图片地址。 xml中使用自定义属性:
imageUrl
loadImage
imageView
<ImageView android:layout_width="120dp" android:layout_height="120dp" android:scaleType="centerCrop" app:imageUrl="@{user.picUrl}" />
这样就可以在DataBinding中使用Glide来加载图片了,此外,BindingAdapter也是允许设置多个属性:
@BindingAdapter({"imageUrl", "placeHolder", "error"}) public static void loadImage(ImageView view, String url, Drawable holderDrawable, Drawable errorDrawable) { Glide.with(imageView.getContext()) .load(url) .placeholder(holderDrawable) .error(errorDrawable) .into(imageView); }
如果ImageView对象同时使用了imageUrl、placeHolder和error,并且imageUrl是字符串,placeHolder和error是Drawable,就会调用适配器
placeHolder
error
Drawable
<ImageView android:layout_width="120dp" android:layout_height="120dp" android:scaleType="centerCrop" app:imageUrl="@{user.picUrl}" app:placeHolder="@{@drawable/loading}" app:error="@{@drawable/error}" />
对象转换
Object
ObservableMap
<TextView android:text='@{userMap["lastName"]}' android:layout_width="wrap_content" android:layout_height="wrap_content" />
表达式中的userMap对象会返回一个值,该值会自动转换为用于设置android:text特性值的setText(CharSequence)方法中的参数类型。如果参数类型不明确,则必须在表达式中强制转换返回类型。 注意,还可以使用object.key表示法引用映射中的值。例如,以上示例中的@{userMap["lastName"]}可替换为@{userMap.lastName}。
userMap
android:text
setText(CharSequence)
object.key
@{userMap["lastName"]}
@{userMap.lastName}
android:background
color
<View android:background="@{isError ? @color/red : @color/white}" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
每当需要Drawable且返回整数时,int都应转换为ColorDrawable。您可以使用带有BindingConversion注释的静态方法完成这个转换,如下所示:
ColorDrawable
BindingConversion
@BindingConversion public static ColorDrawable convertColorToDrawable(int color) { return new ColorDrawable(color); }
但是,绑定表达式中提供的值类型必须保持一致。您不能在同一个表达式中使用不同的类型,如以下示例所示:
<View android:background="@{isError ? @drawable/error : @color/white}" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
BindingAdapter负责发出相应的框架调用来设置值。例如,设置属性值就像调用
setText()
方法一样。再比如,设置事件监听器就像调用setOnClickListener()
方法。 数据绑定库允许您通过使用Adapter指定为设置值而调用的方法、提供您自己的绑定逻辑,以及指定返回对象的类型。只要绑定值发生更改,生成的绑定类就必须使用绑定表达式在视图上调用setter方法。您可以允许数据绑定库自动确定方法、显式声明方法或提供选择方法的自定义逻辑。
example
的特性,库自动尝试查找接受兼容类型作为参数的方法setExample(arg)
。系统不会考虑特性的命名空间,搜索方法时仅使用特性名称和类型。 以android:text="@{user.name}"
表达式为例,库会查找接受user.getName()
所返回类型的setText(arg)
方法。如果user.getName()
的返回类型为String
,则库会查找接受String
参数的setText()
方法。如果表达式返回的是int
,则库会搜索接受int
参数的setText()
方法。表达式必须返回正确的类型,您可以根据需要强制转换返回值的类型。 即使不存在具有给定名称的特性,数据绑定也会起作用。然后,您可以使用数据绑定为任何setter
创建特性。例如,支持类DrawerLayout
没有任何特性,但有很多setter
。以下布局会自动将setScrimColor(int)
和setDrawerListener(DrawerListener)
方法分别用作app:scrimColor
和app:drawerListener
特性的setter
:setter
方法。在这些情况下,某个特性可能会使用BindingMethods
注释与setter
相关联。注释与类一起使用,可以包含多个BindingMethod
注释,每个注释对应一个重命名的方法。绑定方法是可添加到应用中任何类的注释。在以下示例中,android:tint
属性与setImageTintList(ColorStateList)
方法相关联,而不与setTint()
方法相关联:Glide
,或者是其他的图片加载框架,由于这些框架一般通过url
给ImageView
设置图片的,但是ImageView
中并没有设置url
的属性,这个时候,BindingAdapter就派上用场了:imageUrl
就是属性的名称,当ImageView
中使用imageUrl
属性时,会自动调用loadImage
方法,参数imageView
为当前使用imageUrl
属性的ImageView
,参数url
为图片地址。 xml中使用自定义属性:这样就可以在DataBinding中使用
Glide
来加载图片了,此外,BindingAdapter也是允许设置多个属性:如果
ImageView
对象同时使用了imageUrl
、placeHolder
和error
,并且imageUrl
是字符串,placeHolder
和error
是Drawable
,就会调用适配器Object
时,库会选择用于设置属性值的方法。Object
会转换为所选方法的参数类型。对于使用ObservableMap
类存储数据的应用,这种行为非常便捷,如以下示例所示:表达式中的
userMap
对象会返回一个值,该值会自动转换为用于设置android:text
特性值的setText(CharSequence)
方法中的参数类型。如果参数类型不明确,则必须在表达式中强制转换返回类型。 注意,还可以使用object.key
表示法引用映射中的值。例如,以上示例中的@{userMap["lastName"]}
可替换为@{userMap.lastName}
。android:background
特性需要Drawable
,但指定的color
值是整数。以下示例展示了某个属性需要Drawable
,但结果提供了一个整数:每当需要
Drawable
且返回整数时,int
都应转换为ColorDrawable
。您可以使用带有BindingConversion
注释的静态方法完成这个转换,如下所示:但是,绑定表达式中提供的值类型必须保持一致。您不能在同一个表达式中使用不同的类型,如以下示例所示: