简介
DataBinding 是 Google 在 Jetpack 中推出的一款数据绑定的支持库,利用该库可以实现在页面组件中直接绑定应用程序的数据源。使其维护起来更加方便,架构更明确简介。
如何使用
启用 DataBinding
首先设置使用 Databinding,在 app module 的 build.gradle 中添加如下代码即可:
1 | android { |
布局绑定
在使用 DataBinding 时就不能按照之前的方式来编写布局文件了,布局文件的跟布局应该是 layout,layout 中同时存放要绑定的数据及布局,如下:
1 | <?xml version="1.0" encoding="utf-8"?> |
layout 为跟布局,data 节点中存放数据,下面就是我们常见的布局文件。
data 中的 variable 标签为变量,类似于我们定义了一个变量,name 为变量名,type 为变量全限定类型名,包括包名。布局中通过 @{} 来引用这个变量的值,{} 中可以是任意 Java 表达式,但不推荐使用过多的代码。
我们可以使用 import 语法来导入类,以及使用 alias 设置别名:
1 | <data> |
我们也可以通过 default 字段设置默认值:
1 | <TextView android:layout_width="wrap_content" |
绑定数据
我们再新建一个类似上述示例代码中的 DataBinding 布局文件 activity_main.xml 之后,Gradle 会根据布局创建一个 ActivityMainBinding 类,我们需要获取该对象来绑定数据。
使用 DataBinding 时,我们不需要再按照之前的 setContentView 的方式来设置布局到 Activity 中,应该通过 DataBindingUtil#setContentView 来设置,该方法会返回对应的 DataBinding 对象,例如我们创建的布局文件为 activity_main,那么生成的就是 ActivityMainBinding,我们可以通过在 data 节点使用 class 关键字更改这种默认的名字:
1 | <data class=".MainActivityBinding"> |
前面的 . 号表示使用当前包名,也可以使用全限定包名指定。
然后是获取绑定类:
1 | override fun onCreate(savedInstanceState: Bundle?) { |
我们先获取 DataBinding 对象,然后设置 variable 数据,lifecycleOwner 适用于管理生命周期的方法,设置后 Databinding 可以感知到 Activity 的生命周期,保证数据在可见时才会更新,不可见时不会更新数据。
如果是在 Fragment/ListView/RecyclerView 中,我们可以通过下面的方法获取 DataBinding:
1 | binding = ActivityMainBinding.inflate(layoutInflater, null, false) |
绑定普通数据
DataBinding 可以绑定普通数据对象(非 Observable/LiveData),例如上述例子中绑定了一个 String 类型的数据。绑定普通数据我们只需要按照上述的代码设置即可。
绑定可观察数据
绑定可观察数据意味着当数据变化时 UI 会跟着一起变化,绑定可观察数据有三种方式:objects、fields 和 collections.
对单个变量的绑定:fields
对于一些数据类,如果我们不想继承 BaseObservable 或者只需要其中几个字段支持可观察,那么可以使用这种方式来创建可观察数据:
1 | class User { |
对于基本类型和 Parcelable 我们可以直接使用对应的包装类:
- ObservableBoolean
- ObservableByte
- ObservableChar
- ObservableShort
- ObservableInt
- ObservableLong
- ObservableFloat
- ObservableDouble
- ObservableParcelable
引用类型使用带有泛型参数的 ObservableField 类来创建:1
var name = ObservableField<String>()
泛型参数为数据类型。
对集合的绑定:collections
我们同样可以在布局中绑定集合中的某个元素,当集合中的数据发生变化后会同步更新到 UI。
1 | <?xml version="1.0" encoding="utf-8"?> |
绑定数据到 UI 中:
1 | val map = ObservableArrayMap<String, Any>().apply { put("count", 0) } |
绑定对象:objects
这种是最常用的一种方式,需要绑定的数据实体类继承 BaseObservable:
1 | class Person : BaseObservable() { |
首先要在需要支持可观察的数据上添加 @get:Bindable 注解,然后重写 set 方法,在其中调用 notifyPropertyChanged 方法表示更新该数据,BR 是自动生成的,包名跟当前包名一致,会根据 Bindable 注解的变量生成对应的值;也可以调用 notifyChange() 方法更新所有数据。
绑定 LiveData
LiveData 目前也支持数据绑定,绑定方式跟上述介绍的一样:
1 | <?xml version="1.0" encoding="utf-8"?> |
我们可以直接将 LiveData 赋值给 text,然后绑定数据:
1 | val desc = MutableLiveData<String>() |
需要注意的是,老版本的 Gradle 是不支持 LiveData 的绑定的,需要更新到 Gradle 3.4 及以上。
另外,使用 LiveData 有个显示,更新 LiveData 数据时必须在主线程才行。
双向绑定
上述的单向绑定是指数据变化后更新 UI,而双向绑定是指其中任意一个变化后都会同步更新到另一个。
双向绑定使用 @={} 表达式来实现:
1 | <data> |
事件绑定
事件绑定其实跟数据绑定一样,本质上就是将监听器对象绑定到 UI 元素上:
1 | <?xml version="1.0" encoding="utf-8"?> |
然后我们写好监听事件,绑定到 binding 中即可:
1 | class MainActivity : AppCompatActivity() { |
自定义参数绑定:BindingAdapter
目前已经支持的双向绑定的参数列表如下:
除了上述的参数外,我们也可以使用 BindingAdapter 创建自定义参数。
例如我们需要使用 Glide 加载网络图片,可以先创建一个使用了 BindingAdapter 注解的函数,注解中的字段为参数名,函数的第一个参数必须为目标 View 或者其子类,因此使用 Kotlin 时我们可以定义为扩展函数,这样使用很方便。
1 | "imageUrl") ( |
然后我们就可以在布局代码中直接使用该参数加载图片:
1 | <ImageView |
好了,DataBinding 差不多就讲到这里了.