1.理论基础
数据绑定库是一个支持库,可让您使用声明性格式(而不是以程序化方式)将布局中的界面组件绑定到应用中的数据源。
布局通常使用调用界面框架方法的代码在 activity 中定义。例如,以下代码会调用 findViewById()
来查找 TextView
widget 并将其绑定到 viewModel
变量的 userName
属性:
TextView textView = findViewById(R.id.sample_text);
textView.setText(viewModel.getUserName());
以下示例展示了如何使用数据绑定库直接在布局文件中将文本分配给 widget。这样便无需调用上述任何 Java 代码。请注意在赋值表达式中使用 @{}
语法:
<TextView
android:text="@{viewmodel.userName}" />
这样做的好处英文原文如下:
Binding components in the layout file lets you remove many UI framework calls in your activities, making them simpler and easier to maintain. This can also improve your app's performance and help prevent memory leaks and null pointer exceptions.
2.代码实现步骤
step1
app模块中的build.gradle配置databinding。
dataBinding{
enabled=true
}
step2
把XML布局文件转换为DataBinding可以识别和绑定的布局文件。
选中根节点LinearLayout,按Alt+Enter弹出快捷菜单Convert to data binding layout。
LinearLayout布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
转换后布局文件:增加了<layout>包裹。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</layout>
step3
实例化布局文件对象,xml布局转成类对象。
activity_main对应的布局文件对象的命名采用了大驼峰命名ActivityMainBinding。使用ActivityMainBingding对象就可以操控UI控件。
step4
在activity_main.xml布局文件声明变量
创建User类,并在布局文件中的data标签底下声明这个User类型的变量。
public class User {
public String userName;
public String password;
}
<data>
<variable
name="user"
type="com.wellsun.onewaydatabinding.User" />
</data>
step5
在组件中使用变量
@{变量},这样就完成了数据源和UI控件的绑定,数据源值变,UI控件的值变。
<EditText
android:text="@{user.userName}"
android:layout_margin="20dp"
android:id="@+id/edtUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入用户名" />
step6
给ActivityMainBinding赋值,默认是空值。
方式1:
activityMainBinding.setUser(user);
方式2:
activityMainBinding.setVariable(BR.user,user);
3.示例代码
整体布局文件和Activity如下代码:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.gaoting.onewaydatabinding.User" />
<variable
name="goods"
type="com.gaoting.onewaydatabinding.Goods" />
<variable
name="Alia"
type="String" />
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:text="@{user.userName}"
android:layout_margin="20dp"
android:id="@+id/edtUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入用户名" />
<EditText
android:text="@{user.password}"
android:layout_margin="20dp"
android:id="@+id/edtPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入密码" />
<TextView
android:text="@{Alia}"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:text="@{goods.goodsName}"
android:layout_margin="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:layout_margin="20dp"
android:id="@+id/btChangeUser"
android:text="改变用户名为gao,密码为123"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<Button
android:layout_margin="20dp"
android:id="@+id/btResume"
android:text="恢复为初始用户名和密码"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
</layout>
UI控件
MainActivity.java
package com.gaoting.onewaydatabinding;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.databinding.DataBindingUtil;
import com.gaoting.onewaydatabinding.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding activityMainBinding;
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
//从值到UI的一个映射(单向绑定,数据员与UI控件)
user = new User();
user.userName = "gaoting";
user.password="123456";
activityMainBinding.setUser(user);
activityMainBinding.btChangeUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
user.userName="gao";
user.password = "123";
activityMainBinding.setVariable(BR.user,user);
}
});
activityMainBinding.btResume.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
user.userName="gaoting";
user.password = "123456";
activityMainBinding.setUser(user);
}
});
activityMainBinding.setAlia("John");
Goods goods = new Goods();
goods.goodsName="夹克衫";
activityMainBinding.setGoods(goods);
}
}