Android Architecture Component DataBinding -- Binding adapters(翻译)
Android Architecture Component DataBinding – Binding adapters(翻译)
原文:https://developer.android.com/topic/libraries/data-binding/binding-adapters
Binding adapters 负责对设置值进行适当的框架调用。一个例子是像调用 setText()
) 方法去设置属性值。另一个例子是像调用 setOnClickListener()
) 方法去设置一个事件监听器。
Data Binding 库允许你去指定设置一个值的方法,提供你自己的绑定逻辑,以及通过使用 adapters 来指定返回对象的类型。
设置属性值
每当绑定的值改变,生成的绑定类必须调用一个 view 的表达式 的 setter 方法。你可以让 Data Binding 自动确定方法,显式声明方法或提供自定义逻辑以选择方法。
自动选择方法
对于名为 name
的属性,库会自动尝试寻找方法 setExample(arg)
,它接受一个相应的类型作为参数。不考虑属性的命名空间,在搜索方法时只使用属性名称和类型。
举个例子,给定 android:text="@{user.name}"
表达式,库会自动寻找一个 setText(args)
的方法,它接收一个 user.getName()
返回值的类型的参数。如果 user.getName()
返回类型是 String
,库会去寻找一个接收一个 String
类型参数的 setText()
方法。如果 user.getName()
返回类型是 int
,库会去寻找一个接收一个 int
类型参数的 setText()
方法。表达式必须返回正确的类型,必要时你可以去对返回值进行转型。
甚至没有给定名字的属性存在,Data Binding 也能正常工作。你可以通过 data binding 为任何 setter 创建属性。下面 layout 自动使用 setScrimColor(int)
) 和 setDrawerListener(DrawerListener)
) 方法作为 app:scrimColor
和 app:drawerListener
属性的 setter 方法。分别为:
1 | <android.support.v4.widget.DrawerLayout |
指定自定义方法名
一些属性的 setter 与名称不匹配。在这种情况下,属性可以使用 BindingMethods
注解进行 setter 的关联。注解可以与类一起使用,并且可以包含多个 BindingMethod
注解,每一个都有一个重命名的方法。BindingMethods 注解可以被加在你 app 中的任何类上面。下面的例子中,android:tint
属性与 setImageTintList(ColorStateList)
) 方法关联,而不是 setTint()
方法:
1 |
|
大多数情况下,你不需要重命名 Android Framework 类中的 setters。属性已经使用名称约定实现了自动查找匹配方法。
提供自定义逻辑
一些属性需要自定义绑定逻辑。举个例子,没有一个与 android:paddingLeft
属性关联的 setter。但是提供了 setPadding(left, top, right, bottom)
。一个带有 BindingAdapter
注解的,静态的 binding adapter 方法可以允许你自定义属性调用的 setter 是怎么样的。
Android Framework 类的属性已经创建了 BindingAdapter
注解。举例,下面的例子展示了 paddingLeft
属性的 binding adapter:
1 |
|
参数类型是很重要的,第一个参数决定了与属性相关联的 view 的类型。第二个参数决定了给定属性表达式中接收的类型。
Binding adapter 对其它类型的自定义是很有用的。举例,一个工作线程中自定义加载器可以被调用来加载图片。
如果与 Android Framework 冲突,你定义的 binding adapters 会覆盖它。
你的 adapters 也可以接收多个属性,如下:
1 |
|
你可以如下在你的 layout 中使用 adapter。注意,@drawable/venueError
引用了你 app 中的 resource。使用 @{}
包围使它成为一个合法的 binding 表达式。
1 | <ImageView app:imageUrl="@{venue.imageUrl}" app:error="@{@drawable/venueError}" /> |
Data Binding Library 忽略了自定义命名空间以用于匹配。
如果,imageUrl
和 error
都被 ImageView
对象使用,并且 imageUrl
是一个 String,error
是一个 Drawable
,adapter 就会被调用。如果你希望它们任何属性被调用时就让 adapter 调用,你可以设置 requireAll
) 标志为 false
,如下:
1 |
|
当有冲突时,你的 binding adapters 覆盖默认的 data binding adapters。
Binding adapter 方法可以选择在处理器中返回旧值。一个方法声明旧值和新值时应该首先声明 所有 属性的旧值,然后再是新值,如下:
1 |
|
事件处理器只能与只有一个抽象方法的接口或抽象类一起使用,如下:
1 |
|
如下在你的 layout 中使用事件处理器:
1 | <View android:onLayoutChange="@{() -> handler.layoutChanged()}"/> |
当一个监听器有多个方法,必须要把它分割成多个监听器。比如,View.OnAttachStateChangeListener
有两个方法:onViewAttachedToWindow(View)
) 和 onViewDetachedFromWindow(View)
)。对此,库提供了两个接口来区分属性和处理器:
1 | // Translation from provided interfaces in Java: |
因为改变其中一个监听器也会影响另一个,所以你需要一个任意或者全部属性的 adapter。你可以在注解中设置 requireAll
) 为 false
来指定不是所有属性都必须设置一个绑定表达式,如下:
1 |
|
上面的例子比一般的稍微复杂一点,因为 View
类使用 addOnAttachStateChangeListener()
) 和 removeOnAttachStateChangeListener()
) 方法而不是 OnAttachStateChangeListener
的 setter 方法。android.databinding.adapters.ListenerUtil
类帮助保持跟踪之前的监听器,以便于它们在 binding adapter 中便于移除。
通过在接口 OnViewDetachedFromWindow
和 OnViewAttachedToWindow
添加 @TargetApi(VERSION_CODES.HONEYCOMB_MR1)
注解,data binding 代码生成器知道 监听器应该只会在 Android 3.1(API level 12)及以上才会生成,支持的版本与 addOnAttachStateChangeListener()
) 方法相同。
对象转化
自动对象转化
当一个 Object
从绑定表达式中返回时,库选择方法来设置属性的值。Object
被转换为所选方法的参数类型。使用 ObservableMap
类来存储数据这个行为在 app 中是很方便的,如下:
1 | <TextView |
你也可以使用 object.key 的方式引用值。比如,上面例子中的 @{userMap[“lastName”]} 可以被替换为 @{userMap.lastName}
表达式中的 userMap
对象返回一个值,它自动转型成 用户通过 android:text
属性设置值的 setText(CharSequence)
方法的参数类型。如果参数类型产生歧义的,你必须要在表达式中进行类型转换。
自定义转换
在一些情况下,在两个特殊的类型之间自定义转换是需要的。比如,View 的 android:background
属性期望是一个 Drawable
,但是指定的 color
值是一个 integer。下面的例子展示了属性期望是 Drawable
,但是提供的却是 integer:
1 | <View |
每当期望一个 Drawable
并返回一个 integer 时,int
应该要被转换成一个 ColorDrawable
。这个转换可以通过使用一个带有 BindingConversion
static 的方法做到:
1 |
|
但是,绑定表达式中提供的值类型必须是一致的。不能在同一表达式中使用不同的类型,如下示例所示:
1 | <View |
本文链接:https://blog.wangjiegulu.com/2018/04/15/android_architecture_components_binding_adapters/
版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处。