前言
Android DataBinding
,在如今来看已经不算陌生,在网上也多多少少有好的文章介绍它,很多朋友早就耳闻它的大名,通过学习并运用在自己的项目中。那今天为什么我还要再写一个DataBinding
的教程呢?相信很多朋友和我一样,在学习中发现,网上大部分的教程都存在不同的缺陷,要么内容不完整,要么就是没有系统化的讲解方向,都是一股脑的一篇文章全部抛出。所以针对这些问题,我写下这个教程,帮助那些还没有接触DataBinding
的朋友入门。
注:如果你觉得写得不好或者不详细,请直接批评指出,评论或私信尽情轰炸我吧。
目录
以下是我总结出的学习顺序,可以方便朋友们学习和复习。老规矩,有错误的地方请尽情的批评指出。
初级篇
Android DataBinding(数据绑定)详解(一)
- 什么是DataBinding
- DataBinding的优点及不足
- DataBinding的基础用法
Android DataBinding(数据绑定)详解(二)
- DataBinding原理
Android DataBinding(数据绑定)详解(三)
- 常用的表达式
- 人性化的null检查机制
- include导入其他布局
Android DataBinding(数据绑定)详解(四)
- observable
- 高级绑定
高级篇
Android DataBinding(数据绑定)详解(五)
- 列表绑定
- 列表绑定之番外篇
Android DataBinding(数据绑定)详解(六)
- 自定义属性带来的便捷
- 神奇的双向绑定
Android DataBinding(数据绑定)详解(七)
- 表达式链
- 逼格高的Lambda表达式
Android DataBinding(数据绑定)详解(八)
- DataBinding的动画
- 方便的UI测试
Android DataBinding(数据绑定)详解(九)
- 温故而知新
- 不舍的完结,DataBinding的使用建议
1、什么是DataBinding
DataBinding
是Google在2015年I/O大会介绍的一个帮助开发者处理视图与数据交互的框架(官方原生支持 MVVM),字面理解即为数据绑定。它给我们带来了很大的方便,其中最直接的便是省去findViewById,说到这里,其实网上也有很多注解框架(例如:ButterKnife、AndroidAnnotations),但是与DataBinding
相比还是不好用。在Google官网文档还说,DataBinding
还能提高解析XML的速度,其实DataBinding
的好用,不仅仅体现在可以省去使用很多啰嗦findViewById,还有很多。往下看你就会明白的。
2、DataBinding的优点及不足
优点:
- 节省代码,省去了findViewById()
- 兼容性高,兼容到Android2.1(API 7)
- 支持绝大部分的 Java 写法
- 支持lambda表达式
- 不使用反射,保证了性能
- 数据直接绑定在XML中
- 最新的支持双向绑定
- 支持在任意线程更新数据(列表类型除外)
- 避免了因数据导致的空指针(null)
缺点:
- IDE支持还不那么完善(xml中代码自动补全大部分需要手写)
- 报错信息不那么直接
- 没有重构的支持
- 需要遵循DataBinding的格式
3、DataBinding的基本用法
好了,说了一大堆废话,终于可以开始我们正式的学习和运用了。接来下所有讲解,将在Demo中演示,在最后的文章会提供GitHub地址,请大家安心学习。
第一步,环境搭建:
打开项目,在build.gradle(Module:app)中添加如下代码
android {
...
dataBinding {
enabled = true
}
}
完整代码如下:
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "app.fengjun.com.databinding_demo"
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// DataBinding环境搭建
dataBinding {
enabled = true
}
}
第二步,基础使用:
省去findViewById(赶紧替换ButterKnife吧!)
新建Explain1Activity类并创建对应的activity_explain1.xml布局,在布局最外层嵌套layout,代码如下
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_age"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_clcik"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
android:textAllCaps="false" />
</LinearLayout>
</layout>
布局中有带有id的2个TextView和1个Button,我们将对他们进行操作。注意:当布局外嵌套layout后,系统会自动帮我们生成对应的Binding类,生成类名规则为:布局名称大写+Binding,省去_符号。如果没有生成,需要Rebuild Project。
然后在Explain1Activity中,我们编写如下代码,具体代码如下:
public class Student {
private String name;
private String age;
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public class Explain1Activity extends AppCompatActivity {
private ActivityExplain1Binding binding;
private Student student;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_explain1);
student = new Student("FynnJason", "100");
binding.tvName.setText(student.getName());
binding.tvAge.setText(student.getAge());
binding.btnClcik.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(Explain1Activity.this, "被点击了", Toast.LENGTH_SHORT).show();
}
});
}
}
可以看到,我们用Binding生成的对象去替换原来的setContentView,参数第一是上下文(this),第二个是布局。我们通过这个对象就可以拿到视图中的控件,然后对他们进行操作。那么,省去findViewById就完成了!是不是极其简单。运行效果如图:
虽然效果实现了,但这并没有体现数据绑定的特性啊,不用急,我们修改布局,修改如下:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="student"
type="app.fengjun.com.databinding_demo.explain1.Student" />
<variable
name="presenter"
type="app.fengjun.com.databinding_demo.explain1.Explain1Activity.Presenter" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{student.name}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{student.age}" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{presenter.onClickButton}"
android:text="Button"
android:textAllCaps="false" />
</LinearLayout>
</layout>
public class Explain1Activity extends AppCompatActivity {
private ActivityExplain1Binding binding;
private Student student;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_explain1);
student = new Student("FynnJason", "100");
binding.setStudent(student);
binding.setPresenter(new Presenter());
}
public class Presenter {
public void onClickButton(View view) {
Toast.makeText(Explain1Activity.this, "被点击了", Toast.LENGTH_SHORT).show();
}
}
}
我们在布局文件中,添加了data
便签,在data便签里面又使用了variable
标签,在variable
便签中,name
我们可以自定义,type
就是我们的数据源和方法源,这里对应了Student数据和Present类的方法,这样,我们就省去了设置id,直接对属性进行数据绑定和监听操作,具体是使用@{}语句。
需要注意的是,监听方法需要严格遵循Android规范,比如这里点击事件方法中要传入View(当然方法名称是可以随意的),如果不传会崩的哦!你可能要问了,那如果我真的忘记传了呢,不急,我们还可以用lambda写法,它就不用严格遵循Android规范,但这里不做介绍,毕竟一口吃不成胖子嘛。接下来我们在Activity中要用Binding对象将数据源set进去,相信大家看代码就已经清楚怎么做了(你说没看懂,那我也很绝望啊!QAQ)
然后我们再运行,效果是刚刚一样的,所以这里就不贴图了。大家是不是觉得很神奇!
好了,本次的教程就到底结束了。大家有什么疑问可以在下面评论留言,欢迎批评指出。