build.gradle中开启数据绑定
android {
...
dataBinding {
enabled = true
}
}
数据绑定布局文件略有不同,以布局的根标记layout 开始,后面跟着数据元素data 和视图根元素view。这个视图元素是在非绑定布局文件中的根元素。
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
数据中的user变量描述了可以在此布局中使用的属性。
<variable name="user" type="com.example.User" />
User entity:
public class User {
private final String firstName;
private final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
}
为每个布局文件生成一个绑定类。默认情况下,类的名称基于布局文件的名称,将我们布局文件的首字母大写,并且去掉下划线,将下划线后面的字母大写,加上Binding组成。上面的布局文件名是activity_main。因此,相应生成的类是ActivityMainBinding。该类保存从布局属性(例如user变量)到布局视图的所有绑定,并知道如何为绑定表达式赋值。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("Test", "User");
binding.setUser(user);
}
或者,您可以使用LayoutInflater获得视图,如下面的示例所示:
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
如果您在 Fragment, ListView, or RecyclerView adapter中使用数据绑定项,您可能更喜欢使用绑定类或DataBindingUtil类的inflate()方法,如下面的代码示例所示:
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
支持如下表达式语言
Mathematical + - / * %
String concatenation +
Logical && ||
Binary & | ^
Unary + - ! ~
Shift >> >>> <<
Comparison == > < >= <=
instanceof
Grouping ()
Literals - character, String, numeric, null
Cast
Method calls
Field access
Array access []
Ternary operator ?:
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
//如果左操作数不为空,则选择左操作数;如果右操作数为空,则选择右操作数。
android:text="@{user.displayName ?? user.lastName}"
//上面等价于如下代码
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
集合
<data>
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<variable name="list" type="List<String>"/>
<variable name="sparse" type="SparseArray<String>"/>
<variable name="map" type="Map<String, String>"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
…
android:text="@{list[index]}"
…
android:text="@{sparse[index]}"
…
android:text="@{map[key]}"
您可以使用单引号包围属性值,这允许您在表达式中使用双引号,如下例所示:
android:text='@{map["firstName"]}'
//等同上面
android:text="@{map[`firstName`]}"
网友评论