在Google I/O 2015上,伴随着 Android M 预览版发布了DataBinding兼容函数库。DataBinding可以帮助开发者减少许多重复的代码编写,并且可以提高XML解析速度,同时可以配合MVVM框架提高代码可读性。
编辑器:Android studio 4.1.1
语言:Kotlin 1.3.72
在项目中使用 DataBinding 只需要在 build.gradle 的 android 配置项下添加如下代码即可使用 DataBinding
dataBinding{
enabled true
}
实体类与普通项目实体类定义方式相同,这里我定义了一个 UserInfo 类,代码如下
data class UserInfo(var userName:String,var age:Int,var sex:Int)
我们需要将布局XML文件的结构进行改变,第一个标签需要改为 layout,在layout 中分为两部分,第一部分是 data 标签,主要用于变量定义和类型声明,第二部分是布局标签,在 layout 中只能包含一个布局标签,具体内容如下:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="vm"
type="com.kotlin.kotlinDataBinding.model.MainModel" />
data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".view.MainActivity">
<TextView
android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{vm.user.userName}"
android:layout_marginTop="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/user_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{vm.user.age+""}'
android:layout_marginTop="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/user_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{vm.user.sex==0?"男":"女"}'
android:layout_marginTop="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/user_age" />
androidx.constraintlayout.widget.ConstraintLayout>
layout>
class MainModel {
var user = UserInfo("张三",20,0)
}
通过 variable 标签进行 MainModel 的实体导入,并设置别名为 vm,在需要取值的地方可以通过 @{} 方式进行直接取值,{} 中可以接受 lambda 表达式。
还需要在代码中对数据进行处理,具体处理如下:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_main)
val binding = DataBindingUtil.setContentView(this,R.layout.activity_main) as ActivityMainBinding
val vm = MainModel()
binding.vm = vm
}
}
将以前的 setContentView 方法替换为 DataBindingUtil 中的方法,在XML配置完成后,会自动生产一个类,这个生成类的类名规则如下:将我们布局文件的首字母大写,并且去掉下划线,将下划线后面的字母大写,加上Binding组成。使用这个类便可以直接对XML中的对象进行初始化数据了。
通过上述操作,我们已经可以在XML文件中直接获取值,如果属性值发生了改变,我们就需要通过 Observable 类来进行单向绑定,以此达到属性值改变,视图同时发生改变。具体实现如下:
class MainModel {
var user = ObservableField<UserInfo>(UserInfo("张三",20,0))
fun changeSex(){
user.get()?.let {
if (it.sex == 0){
it.sex = 1
}else{
it.sex = 0
}
user.notifyChange()
}
}
}
我们只需要在 MainModel 里面对需要绑定的对象添加 ObservableField 进行封装即可完成单向绑定,同时在属性值改变时,调用 notifyChange 方法即可通知视图进行改变。
<TextView
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:background="@drawable/btn_bk"
android:gravity="center"
android:onClick="@{()->vm.changeSex()}"
android:text="改变性别"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/user_sex" />
在xml布局文件中,添加了一个按钮,通过 @{()->vm.changeSex()} 绑定点击事件执行的方法。
单向绑定是属性值发生改变时,通知视图进行相应的改变,而双向绑定则是视图发生改变时也会通知绑定的对象属性相应发生改变。双向绑定师傅简单,只需要在 ‘@’ 后加上 ‘=’ 即可,如:
<TextView
android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:text="@={vm.user.userName}"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
注意
android:text='@{vm.user.age+""}'
、android:text='@{vm.user.sex==0?"男":"女"}'
、@{()->vm.changeSex()}
,这类表达式不可进行双向绑定,否则会报错。
使用 DataBinding 可以加快开发速度与代码可读性,同时 DataBinding 可以进行自定义属性的绑定,具体内容将在下篇文章讲解。
代码git地址:https://gitee.com/fylds/kotlin_data-binding.git
本文是在学习过程中编写的,若有错误之处,请指正。