前言:
Data binding 在2015年7月发布的Android Studio v1.3.0 版本上引入,在2016年4月Android Studio v2.0.0 上正式支持。目前为止,Data Binding 已经支持双向绑定了。
Databinding 是一个实现数据和UI绑定的框架,在这之前,我们不可避免地要编写大量的毫无营养的代码,如 findViewById()、setText(),setVisibility(),setEnabled() 或 setOnClickListener() 等,通过 Data Binding , 我们可以通过声明式布局以精简的代码来绑定应用程序逻辑和布局,提高开发效率、
虽然也有ButterKnife,RoboBinding等,但是DataBinding性能高,功能全。所以不用犹豫,在你的项目中用吧。
谷歌的官方文档。
主要优势:
1.去除Activity和Fragment中无用的UI代码
2.性能超过手写代码(不会用id出错crash)
3.保证执行在主线程中。
集成:
首先保证自己的AS版本是2.0以上,然后在项目的gradle中添加,然后编译下。
android {
...
dataBinding{
enabled=true;
}
...
}
使用方法:
1.在布局文件中,最外面套一层layout标签。
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.young.databindingdemo.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>
</RelativeLayout>
</layout>
2。activity中获取:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//添加布局,ActivityMainBinding命名方式是根据布局文件的命名方式来的
ActivityMainBinding binding= DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
//直接取到了id为tv_hello的textview标签
binding.tvHello.setText("data Binding");
}
}
以上只是简单的去除findviewbyid获取空间的用法,但是dataBinding的强大之处远不止于此。
XML中数据绑定:
1.我们先新建一个实体javabean类User
public class User {
private String name;
private int age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
}
2.来看我们如何在xml中添加实体数据:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.young.databindingdemo.data.User"/>
</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:gravity="center"
android:padding="12dp"
android:text="@{user.name}"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="12dp"
android:text="@{user.age}"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="12dp"
android:text="@{user.sex}"/>
</LinearLayout>
</layout>
可以看到
<data>
<variable
name="user"
type="com.young.databindingdemo.data.User"/>
</data>
data标签将数据引用启用,name是自己定义的对象的名字,type是类的全路径
也可以写成如下的形式:
<data>
<import type="com.young.databindingdemo.data.User" alias="myUser"/>
<variable
name="user"
type="User"/>
</data>
所以type也是可以写成String,int ArrayList等形式。alias防止包名一样。
3.我们来看Activity中如何使用:
public class DataActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityDataBinding binding= DataBindingUtil.setContentView(DataActivity.this, R.layout.activity_data);
binding.setUser(new User("young","male",25));
}
}
这样数据就会显示,Activity中无需写settext代码。
XML事件绑定:
事件绑定有两种方式,先看第一中,方法引用,特点:自定义一个类,定义一个方法,方法中的参数和要绑定的事件参数一致。textview点击事件如下:
listener事件类:
public class handleClick {
public void OnClickHandle(View view){
Log.i("ssssss","click");
}
}
layout:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="click"
type="com.young.databindingdemo.handleClick"/>
</data>
<LinearLayout
android:orientation="vertical"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_hello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{click.OnClickHandle}"
android:gravity="center"
android:text="data binding"
android:background="#0f0"
android:padding="12dp"/>
</LinearLayout>
</layout>
要注意data的数据引用和onClick中点击事件的写法,方法一定不要加()。另一种写法为:android:onClick=”@{click::OnClickHandle}”
activity代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//添加布局,ActivityMainBinding命名方式是根据布局文件的命名方式来的
ActivityMainBinding binding= DataBindingUtil.setContentView(MainActivity.this,R.layout.activity_main);
//直接取到了id为tv_hello的textview标签
binding.setClick(new handleClick());
}
}
注意:data中引用的外部数据一定都要在Activity中set进去。
点击事件第二种方式:监听器绑定。
与第一种方法类似,但是这种方式可以设置自己的方法参数
如:
public class handleClick {
//方法引用
public void OnClickHandle(View view){
Log.i("ssssss","click");
}
//监听器绑定
public void OnClickHandle2(){
Log.i("ssssss","click2");
}
}
layout的写法也有区别:
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="click"
type="com.young.databindingdemo.handleClick"/>
</data>
<LinearLayout
android:orientation="vertical"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_hello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{click::OnClickHandle}"
android:gravity="center"
android:text="clikc1"
android:background="#0f0"
android:padding="12dp"/>
<TextView
android:id="@+id/tv_hello2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{()->click.OnClickHandle2()}"
android:gravity="center"
android:background="#00f"
android:text="clikc2"
android:padding="12dp"/>
</LinearLayout>
</layout>
可以看到,就是onClick的写法区别,整体是一个lambda写法,方法要完整。
XML中支持逻辑判断
比如:
<TextView
android:id="@+id/tv_hello3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text='@{1>2?"3":"5"}'
android:background="#f00"
android:padding="12dp"/>
注意:text不支持int类型,所以3和5要是String类型才行。
下面我们就来看看表达式支持的一下语法和不支持的语法
支持的表达式:
Mathematical + - / * %
String concatenation +
Logical && ||
Binary & | ^
Unary + - ! ~
Shift >> >>> <<
Comparison == > < >= <=
instanceof
Grouping ()
Literals - character, String, numeric, null
Cast
Method calls
Field access
Array access []
Ternary operator ?:
不支持的表达式:
this
super
new
Explicit generic invocation
null检查
DataBinding会自动null的判断,比如我们定义的User类,如果引用的user.age没有赋值,会有默认值,不会因为null而crash。
以上只是DataBinding的小试牛刀,很多高级的功能欢迎click下篇文章。