概述
DataBinding使用指南(一):布局和binding表达式
DataBinding使用指南(二):使用可观察的数据对象
DataBinding使用指南(三):生成binding类
DataBinding使用指南(四):BindingAdapter
DataBinding使用指南(五):绑定布局视图到架构组件
文章目录
- 创建Binding对象
- 带ID的View
- 变量
- ViewStub
- 立即Binding
- 高级Binding
- 动态变量
- 后台线程
- 自定义binding类名
DataBinding库会帮我们生成用于访问布局中的变量和View 的Binding类,这一节将说明如何创建和自定义生成的Binding类。
DataBinding库会为每个布局文件生成一个binding类,生成的 binding 类将布局中的 View 与布局变量链接起来,并且我们可以自定义binding 类的名称和包,另外所有生成的 binding 类都继承自ViewDataBinding 。
默认情况下,该类的名称基于布局文件的名称,将布局名称转换为Pascal格式并向其添加Binding后缀。例如布局文件名是 activity_main.xml
,相应的生成MainActivityBinding
类 。这个类持有了布局属性(例如user
变量)到布局View的所有绑定,并知道如何为绑定表达式分配值。
创建Binding对象
binding 对象应该在 inflat 布局后立即创建,以确保 View 层次在绑定到布局中的表达式视图之前不被修改。将对象绑定到布局的最常见方法是使用绑定类的静态方法,我们可以先将视图层次inflate ,然后使用 binding类的inflate()
方法,,膨胀视图层次结构并将其绑定到该层次结构,如下例所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater());
}
还有另一个版本inflate()
方法,它除了LayoutInflater
对象之外还需要一个ViewGroup
对象,请看下面的例子:
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
如果使用不同的机制 inflate 布局,则可以分别进行绑定,如下所示:
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
有时候预先不知道绑定类型,在这种情况下,可以使用DataBindingUtil
类创建绑定 ,如下面的代码片段所示:
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId,
parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bindTo(viewRoot, layoutId);
如果我们在一个Fragment
, ListView
或RecyclerView
的Adapter中使用数据绑定 Item,我们可能更偏向于使用绑定类的 inflate()
方法 或 DataBindingUtil
类,如下面的代码所示:
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
带ID的View
DataBinding库会在binding类中为布局中每个具有ID的View创建一个不可变字段。例如,DataBinding库从以下布局创建TextView
类型的firstName
和lastName
字段:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
DataBinding库一次性从View层次结构中提取包含ID的View,此机制要比调用findViewById()`方法访问View更快。
ID在数据绑定中并不是必须的,但有些情况下仍然需要在代码中访问View。
变量
Databinding库会为布局中声明的每个变量生成访问器方法。例如,下面布局的binding类中会为user,image和note变量生成 setter 和getter方法:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
ViewStub
与普通View不同,ViewStub
对象以不可见View开始,当它变得可见时,或被明确告知 inflate 时,他们通过 inflate 另一个布局来替换自身。
由于ViewStub
实质上从 View层次结构中消失了,binding对象中的View也必须消失以便垃圾回收。因为这些View是 final 的,所以在生成的绑定类中一个 ViewStubProxy
对象会替代ViewStub
,让我们可以在ViewStub
存在的情况下访问它,并在ViewStub
已经 inflate时访问 inflated 的 View 层次结构。
当 inflating另一个布局时,必须为新布局建立绑定,因此,ViewStubProxy
必须要监听ViewStub
的 OnInflateListener
并在必要时建立绑定。由于在给定时间只有一个监听器可以存在,所以 ViewStubProxy
允许我们设置一个OnInflateListener
,它在建立绑定后调用。
立即Binding
当一个变量或可观察对象发生更改时,绑定会安排在下一帧更改之前。然而,有时候,绑定必须立即执行,要想强制执行,请使用 executePendingBindings()
方法。
高级Binding
动态变量
有时候,特定的绑定类是未知的。例如,RecyclerView.Adapter
针对任意布局进行操作,所以不知道特定的binding类,但它仍然必须在调用onBindViewHolder()
方法期间分配 binding 值。
在下面示例中,RecyclerView
绑定的所有布局都有一个 item
变量,该BindingHolder
对象有一个getBinding()
方法,会返回ViewDataBinding
基类 。
public void onBindViewHolder(BindingHolder holder, int position) {
final T item = mItems.get(position);
holder.getBinding().setVariable(BR.item, item);
holder.getBinding().executePendingBindings();
}
注意:DataBinding库会在模块包中生成一个名为
BR
的类,其中包含用于数据绑定的资源的ID。在上面的例子中,DataBinding库自动生成了BR.item
变量。
后台线程
我们可以在后台线程中更改数据模型,只要它不是集合。 DataBinding在计算期间会本地化每个变量或字段以避免任何并发问题。
自定义binding类名
在默认情况下,绑定类根据布局文件的名称生成,以大写字母开头,删除下划线(_),大写接下来的字母,并加上后缀 Binding。该类放在 databinding模块包下的包中。例如,布局文件 contact_item.xml
生成ContactItemBinding
类。如果布局所在模块包是com.example.my.app
,则binding类会被放置在 com.example.my.app.databinding
包中。
我们可以通过调整data
元素的class
属性,将 binding 类进行重命名或放置在不同的包中。例如,以下布局会生成ContactItem
binding类,位于当前模块的databinding
包中:
<data class="ContactItem">
…
</data>
我们可以通过在类名前添加一个句点来在不同的包中生成binding类。以下示例在模块包中生成binding类:
<data class=".ContactItem">
…
</data>
我们也可以在要生成binding类的位置使用完整的包名称。以下示例在com.example
包中创建ContactItem
绑定类 :
<data class="com.example.ContactItem">
…
</data>
本文最近更新日期: 2018年4月26日。
DataBinding使用指南(一):布局和binding表达式
DataBinding使用指南(二):使用可观察的数据对象
DataBinding使用指南(三):生成binding类
DataBinding使用指南(四):BindingAdapter
DataBinding使用指南(五):绑定布局视图到架构组件
最后
以上就是笑点低项链为你收集整理的DataBinding使用指南(三):生成的binding类创建Binding对象带ID的View变量ViewStub立即Binding高级Binding动态变量后台线程自定义binding类名的全部内容,希望文章能够帮你解决DataBinding使用指南(三):生成的binding类创建Binding对象带ID的View变量ViewStub立即Binding高级Binding动态变量后台线程自定义binding类名所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复