DataBinding
是谷歌官方发布的一个框架,顾名思义即为数据绑定,是 MVVM
模式在 Android 上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰。MVVM 相对于 MVP,其实就是将 Presenter
层替换成了 ViewModel
层。DataBinding
能够省去我们一直以来的 findViewById()
步骤,大量减少 Activity 内的代码,数据能够单向或双向绑定到 layout 文件中,有助于防止内存泄漏,而且能自动进行空检测以避免空指针异常
参考博客
启用 DataBinding 的方法是在对应 Model :app
的 build.gradle
文件里加入以下代码,同步后就能引入对 DataBinding
的支持
android {
dataBinding {
enabled = true
}
}
1、在布局文件中绑定指定的变量打开布局文件,选中布局文件的第一行,按住 Alt + 回车键,点击 “Convert to data binding layout”,就可以生成 DataBinding 需要的布局规则
和原始布局的区别在于多出了一个 layout 标签将原布局包裹了起来,data 标签用于声明要用到的变量以及变量类型,要实现 MVVM 的 ViewModel 就需要把数据(Person)与 UI(View)进行绑定,data 标签的作用就像一个桥梁搭建了 View 和 Person 之间的通道
Person类
public class Person {
private String name;
private int age;
public Person(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;
}
}
在 data 标签里声明要使用到的变量名、类的全路径(如果 Person类型要多处用到,也可以直接将之 import 进来,就不用每次都指明整个包名路径)
<data>
<variable
name="per1"
type="com.example.databindingpro.Person" />
<variable
name="work"
type="String" />
</data>
如果存在 import 的类名相同的情况,可以使用 alias 指定别名
<data>
<import type="com.leavesc.databinding_demo.model.User" />
<import
alias="TempUser"
type="com.leavesc.databinding_demo.model2.User" />
<variable
name="userInfo"
type="User" />
<variable
name="tempUserInfo"
type="TempUser" />
</data>
这里声明了一个 Person
类型的变量per1
,我们要做的就是使这个变量与两个 TextView 控件挂钩,通过设置per1
的变量值同时使 TextView
显示相应的文本 完整的布局代码如下所示
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="per1"
type="com.example.databindingpro.Person" />
<variable
name="work"
type="String" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{per1.name}"
android:textSize="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(per1.age)}"
android:textSize="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{work}"
android:textSize="30dp"/>
</LinearLayout>
</LinearLayout>
</layout>
通过 @{per1.name
}使 TextView 引用到相关的变量,DataBinding
会将之映射到相应的 getter
方法 之后可以在 Activity 中通过 DataBindingUtil
设置布局文件,省略原先 Activity 的 setContentView()
方法,并为变量per1
赋值
import androidx.databinding.DataBindingUtil;
import android.app.Activity;
import android.os.Bundle;
import com.example.databindingpro.databinding.ActivityMainBinding;
public class MainActivity extends Activity {
private ActivityMainBinding mActivityMainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
mActivityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
com.example.databindingpro.Person person = new com.example.databindingpro.Person("张三",23);
mActivityMainBinding.setPer1(person);//给布局文件name="per1"传入数据,类型为Person对象
mActivityMainBinding.setWork("Teacher");//给布局文件name="work"传入数据,类型为String字符串
}
}
效果: