_StriveG Blog

databinding基础知识

前言

google出的databinding库,相信很多人都已经使用了,经过这么长时间的发展,是时候放到项目里使用了。

基本用法

开启databiding

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

注意:建议使用最新版的Android studio,我在使用的过程中发现as 2.2版本,databinding的双向绑定有点小问题。

将我们的布局文件做稍许的修改。

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<LinearLayout>
</LinearLayout>
</layout>

分为两部分,data数据部分以及原先的布局两部分。

绑定数据

要向绑定数据,我们要准备好bean,这里我准备一个Student,有name和age两个属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Student {
private String name;
private int 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;
}
}

然后,我们在布局中,使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<import type="String"/>
<variable
name="student"
type="com.guolei.baseuse.Student"/>
</data>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.guolei.baseuse.BaseUseActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="@{student.name}"
android:gravity="center"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="@{String.valueOf(student.age)}"
android:gravity="center"
/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
</layout>

注意 :

  • 我们在data下用variable声明了一个类型为Student的变量student,
  • 我们用import将String 这个类导进来,然后我们就可以在这里使用String的一些静态方法了
  • 我们用@{}语法来使用变量的属性,如name,age等

完成这些之后,我们需要make一些module,这个过程会生成我们后面需要使用的一些中间文件和类。

最后,在Activity中,生成binding并且绑定变量。如下

1
2
3
4
5
ActivityBaseUseBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_base_use);
Student student = new Student();
student.setName("_StriveG");
student.setAge(22);
binding.setStudent(student);

这样,数据就绑定在了布局上。

生成的binding类

生成的binding类中,包含我们布局的很多信息。那么,我们如何构造一个binding对象呢。有下面几种办法

  • DataBindingUtil中提供了一些方法,如setcontentview,inflate,bind,getbind等等一些办法,
  • 同样,生成的具体binding类,如上面的ActivityBaseUseBinding中,也有inflate、bind等办法,不过,推荐使用DataBindingUtil的

生成的databinding类中,还顺带生成了,我们在布局文件中,指定了id的控件,我们可以通过这个类去操作view,省去了我们findviewbyid。

绑定事件

绑定事件有两种方法,方法引用和监听器绑定,分别来说下。

  1. 方法引用

    首先声明一个类,

    1
    2
    3
    4
    5
    public static class MethodRef{
    public void onClick(View view) {
    Log.e(TAG, "onClick: " );
    }
    }
其次,我们需要在布局文件中加入这个变量,并且为onclick属性绑定这个方法。

1
2
3
4
5
6
7
8
9
<variable
name="methodRef"
type="com.guolei.baseuse.EventHandling.MethodRef"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:onClick="@{methodRef::onClick}"
/>
最后,给这个绑定变量,binding.setMethodRef(new MethodRef()) 但是,这里有一个缺点,就是以这种方式绑定的方法,只能有view属性,不能有其他参数,有其他参数的情况下,编译会报错。怎么办呢?监听器绑定
  1. 监听器绑定

与方法绑定类似,不同的是在onclick属性中,我们使用的是如下表达式

1
@{(it)->listener.onClick(student)} 或者@{()->listener.onClick(it,student)}

上面只是OnClickListener的形式,其他的listener类似。

包含include标签的情况

包含include标签的情况下我们如何给include的布局绑定呢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</LinearLayout>
</layout>

官方例子,懒得自己写了。

set属性

set属性的方法就很简单了,这里分为三种情况。

  1. android:xxx属性,通过@{}绑定即可
  2. 若为自定义控件,则app:xxx ,通过@{}绑定
  3. 如对应的属性没有提供setXXX方法的话,就需要通过@BindingAdapter自定义,举个例子
1
2
3
4
@android.databinding.BindingAdapter("app:progress")
public static void setProgress(View view,int progress) {
view.setPreogress(progress);
}
  • 注意,方法一定要是static的
  • 这样,我们就能在不居中通过app:progress来指定属性了

总结

这篇只说明了一些很简单很简单的基础用法,下篇会出一些比较高级的用法。当然,这篇中很多基础用法也没介绍完,个人感觉没啥输的,官方文档中很全很详细了。

官方文档,要翻墙!

最近访客