添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
慷慨的鸵鸟  ·  Make ...·  昨天    · 
威武的豌豆  ·  STRING_SPLIT ...·  18 小时前    · 
飘逸的野马  ·  Windows Identity ...·  2 小时前    · 
个性的火柴  ·  【腾讯云Cloud ...·  10 月前    · 
深沉的单杠  ·  java 取出数字部分 ...·  2 年前    · 
谦逊的苦瓜  ·  wpf listbox listview ...·  2 年前    · 

以声明的方式将 observable 数据绑定到 UI 元素
参考 https://developer.android.com/topic/libraries/data-binding/

Get started

添加 dataBinding 元素到项目中 app moudule 的 build.gradle 文件中:

1
2
3
4
5
6
android {
...
dataBinding {
enabled = true
}
}

Layouts & binding expressions

使用 Databinding 的 layout 文件与正常的略微有些不同,它使用了 layout 作为 root tag ,里面包裹着 data 元素和真正的 view 元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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>

其中data 标签包裹着的变量 “ user “ 即为当前 layout 所使用的属性:

1
<variable name="user" type="com.example.User" />

在使用该属性的表达式中,使用 “ @{} “ 的语法来表示引用,这里, TextView 的文字被设置为 user firstName 属性:

1
2
3
4
<TextView 
android:layout_width="wrap_content"
android:layout_height="wrap_content"
ndroid:text="@{user.firstName}" />

表达式应该尽可能的简洁,因为他们不能被单元测试。如果想要简化复杂的表达式,可以使用 Binding adapters。

Data object

先来假设有一个普通的 Java 对象 – User

1
2
3
4
5
6
7
8
public class User {
public final String firstName;
public final String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}

下面这种对象的数据永远不会变,这些数据通常都会被读取一次之后也不会被更改,对象也可以遵循公约定义一些 get 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}
}

从数据绑定的角度来看,上面这两种类的写法是等价的,第一种写法的情况下, android:text 中的 @{user.firstName} 表达式会直接读取该类的 firstName 属性,第二种写法则是直接调用 getFirstName() 方法。另外,如果有 firstName() 方法也会被调用。

Binding data

Binding class 根据 layout 文件自动生成,默认情况下,绑定类的名字根据 layout 文件的名字反向生成并追加 Binding 后缀。上节的 layout 文件名字为 activity_main.xml ,对应的转换后的类名为 MainActivityBinding 。绑定类持有着所有的有关布局信息的绑定,并且知道如何根据绑定的表达式赋值。推荐的做法是在 inflafe layout 的同时创建绑定,如下:

1
2
3
4
5
6
7
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("Test", "User");
binding.setUser(user);
}

gradle 插件版本 3.1.3,亲测 activity_main.xml 生成的类名为 ActivityMainBinding ,并没有反转

在运行时,程序在 UI 上显示了 Test 。另外,也可以通过 LayoutInflater 来获取 view ,示例如下:

1
2
MainActivityBinding binding = MainActivityBinding.inflate(getLayoutInflater());
View view = binding.getRoot();

如果在 Fragment ListView RecyclerView adapter 中使用数据绑定的话,应该使用绑定类的 inflate() 方法,或是 DataBindingUtil ,示例如下:

1
2
3
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

表达式

一般功能

你可以使用下列操作符和关键字:

  • 数学表达式 + - / * %
  • 字符串拼接 +
  • 逻辑操作符 && ||
  • 二进制运算 & | ^
  • 一元运算 + - ? !
  • 比较 == > < >= <=
  • instanceof
  • 分组 ()
  • 字符,字符串,数字,null
  • 数组访问 []
  • 三元运算符号 ?:
  • 示例如下:

    1
    2
    3
    <android:text="@{String.valueOf(index + 1)}"/>
    <android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"/>
    <android:transitionName="@{`image_` + id}"/>

    不支持的操作