一、gradle配置
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
...
buildFeatures{//注意这里 Gradle 5.0之前的版本是dataBinding,5.0之后的版本是buildFeatures
dataBinding = true
}
二、基础使用
1、添加Model实体类
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2、再写布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="student"
type="com.mvvm.model.Student" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{student.name}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(student.age)}" />
</LinearLayout>
</layout>
这里有几个注意点
-
布局文件的顶层标签是layout ,且不需要有其他多余属性(如android:layout_width、android:layout_height)
-
layout 标签下有两部分,一部分是data标签,定义variable变量,name是变量的名称,这个名称是下面布局控件可以直接使用,type是这个变量的类型,也就是全类名。另外一部分是布局标签,注意这里的布局标签,也就是个UI的顶层布局标签,有且应该只有一个。
3、在Activity中将实体类和布局文件进行绑定
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding dataBind = DataBindingUtil.setContentView(this, R.layout.activity_main);
Student std = new Student("Tom",22);
dataBind.setStudent(std);
}
}
这里的DataBindingUtil.setContentView(this, R.layout.activity_main)替换了之前的setContentView(R.layout.activity_main),编译器会在ActivityMainBinding 中生成我们在布局文件里面申明variable 变量student的get和set方法,所以我们在这直接可以调用dataBind.setStudent(std)将model对象直接传给布局文件。这里的dataBind 包含了和布局文件的所有关系,程序也会自动个布局文件里面@{student.age}等相关属性赋值。
4.事件处理
事件处理有两种方式
(1)第一种写法
首先要给需要加事件的控件加上id
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{student.name}" />
然后回到Activity中
dataBind.tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG,"name 的点击事件");
}
});
通过dataBind我们可以拿到布局文件里面指定的控件。然后设置点击事件即可。
(2)第二种写法
在布局文件的data节点上添加属性,声明Onclicklistener变量
<variable
name="Onclicklistener"
type="android.view.View.OnClickListener" />
在需要添事件的控件上引用该属性
<TextView
android:id="@+id/tv_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{Onclicklistener}"
android:text="@{String.valueOf(student.age)}" />
然后在Activity中通过dataBind使用
dataBind.setOnclicklistener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = v.getId();
switch (id){
case R.id.tv_age:
Log.d(TAG,"age 的点击事件");
break;
default:
break;
}
}
});
最后效果
2020-11-22 07:21:44.788 31088-31088/com.mvvm D/MainActivity: name 的点击事件
2020-11-22 07:22:07.050 31088-31088/com.mvvm D/MainActivity: age 的点击事件
5、布局属性
(1)import 属性的使用
<data>
<import type="com.mvvm.bean.Student"/>
<variable
name="student"
type="Student" />
</data>
import 的意义跟在java代码中相同。
如果两个变量的类名相同,则可以用别名(alias)区分
<data>
<import type="com.mvvm.model.Student"/>
<import type="com.mvvm.bean.Student" alias="stud"/>
<variable
name="student"
type="Student" />
<variable
name="stud"
type="Student" />
</data>
6.在布局文件中引入基本数据类型
<variable
name="score"
type="int" />
程序自动导入了java.lang.*包中的所有类,所以基本数据类型无需导包,除了引入基本数据类型,还可以定义List、Map等集合变量
<import type="java.util.ArrayList" />
<variable
name="list"
type="ArrayList<String>" />
注意这里的泛型要用转义字符
使用:
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{list.get(1)}" />
定义Map
<variable
name="key"
type="String" />
<variable
name="map"
type="java.util.Map<String,String>" />
这里Map中的泛型也需要加转义符
使用Map
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{map.get(key)}" />
Activity 中的代码
ArrayList<String> list = new ArrayList<>();
list.add("一");
list.add("二");
list.add("三");
dataBind.setList(list);
dataBind.setKey("name");
Map<String,String> map = new HashMap<>();
map.put("name","小明");
dataBind.setMap(map);