开启DataBinding
在 RecyclerView 中 , 如果要使用DataBinding架构组件进行数据绑定 , 首先要 启用 DataBinding , 并 导入 RecyclerView 依赖 ,
在 Module 模块下的 build.gradle.kts 构建脚本 中 , 配置如下内容 :
build.gradle.kts
1 | android { |
修改主题
新建项目都是Jetpack Compose的主题了,修改为AppCompat的主题
1 |
|
布局
res下新建文件夹layout
添加activity_main.xml
1 |
|
创建的XML可以将光标放置在第一个字符位置 , 按下 Alt + 回车
, 弹出如下下拉菜单 ,转换为DataBinding的XML。
添加实体类
不自动更新
1 | class Student(var name: String, var age: Int) {} |
单向绑定
方式1
如果想单向刷新
类继承BaseObservable
,在需要更新字段的set方法中添加notifyChange();
即可
1 | import androidx.databinding.BaseObservable; |
方式2
该类的属性用ObservableField封装同样的也可以实现单向绑定
1 | public class Person { |
也可以用一下类型
1 | BaseObservable, |
ObservableCollection
dataBinding 也提供了包装类用于替代原生的 List 和 Map,分别是 ObservableList 和 ObservableMap
该对象的属性会自带set和get方法,调用set方法即可实现页面控件绑定的数据自动刷新
1 | public class Presenter{ |
双向绑定
对于输入控件,使用@={}
表达式即可实现页面和绑定的值双向自动刷新
1 | <EditText |
代码中
1 |
|
列表项的XML
list_item_user.xml
1 |
|
创建的list_item_user.xml会自动生成类ListItemUserBinding
RecyclerView.Adapter
1 | import android.view.LayoutInflater |
Activity
1 | import android.os.Bundle |
这里更改属性的时候UI并没有刷新
要想自动刷新
可以把上面的实体使用ObservableField包一下
1 | class Student(var name: ObservableField(String), var age: ObservableField(Int){} |
这样赋值的时候也要调用对应的方法才行,比较麻烦。
建议在页面上再使用ObservableField
包裹。
SwipeRefreshLayout结合
添加依赖
1 | dependencies { |
libs.versions.toml
1 | [versions] |
刷新状态绑定类
RefreshUtils.java
1 | import android.graphics.Color; |
创建ViewModel
BaseViewModel.kt
1 | import androidx.databinding.ObservableBoolean |
MainViewModel.kt
1 | import android.util.Log |
XML
activity_main.xml
1 |
|
Activity
1 | import android.os.Bundle |
XML上的值绑定
数据绑定
字符串
1 | @{student.name} |
数字转字符串
1 | @{String.valueOf(student.age)} |
布尔转字符串
1 | @{enabled ? "真" :"假"} |
字符串拼接
1 | @{"年龄:"+person.age} |
双向绑定
1 | @={content} |
显示
1 | <data> |
方法绑定
不带参数
Activity
1 | public class MainActivity extends AppCompatActivity { |
布局中
在布局文件中,data节点设置该点击事件对象,然后在控件的android:onClick="@{presenter.onClick}"
属性中设置绑定即可。
1 |
|
带参数
1 | public class Presenter{ |
XML中
1 | <Button |
高级用法
DataBinding支持在普通方法上添加@注解来添加自定义控件属性,该方法需满足以下条件:
修饰方法, 要求方法必须public static
方法参数第一个要求必须是View
方法名不作要求
示例:
1 | "imageurl") ( |
使用方法如下:
1 | <ImageView |
ViewBinding与DataBinding区别
1)ViewBinding
ViewBinding会根据xml布局文件自动生成对应的XXXBinding类,然后通过XXXBinding.inflate(layoutInflater)生成一个对应的binding对象, 这个binding对象包含了这个xml布局文件中具有 ID 的所有视图对象,可以直接引用,省去了findViewById的操作。 binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root)
2)DataBinding
DataBinding是一个数据绑定库,它将xml布局中的界面组件绑定到代码中的数据对象, 可以通过对实体字段添@Bindable注解结合notifyPropertyChanged()实现双向绑定,也可以通过对自定义view添加带@BindingAdapter注解的方法来实现自定义属性。 将xml改成databinding 布局后,这样就可以直接绑定并注入xml了: binding = DataBindingUtil.setContentView(this, R.layout.activity_xxx)
通过导包了解,ViewBinding自动生成的XXXBinding也属于DataBinding,也就是DataBinding包含了ViewBinding。