1.DataBinding介绍
2015年谷歌I/O大会上介绍了一个框架DataBinding,DataBinding是一个数据绑定框架,以前我们在Activity里写很多的findViewById,现在如果我们使用DataBinding,就可以抛弃findViewById。DataBinding主要解决了两个问题:
- 需要多次使用findViewById,损害了应用性能且令人厌烦
- 更新UI数据需切换至UI线程,将数据分解映射到各个view比较麻烦
就让我们具体来看看怎么使用它吧。
[注意]:我介绍是基于android stadio1.5及以上开发工具
2.DataBinding的导入
新建MvvMProject项目:
在应用的build.gradle文件中添加如下代码:
android {
//其他的一些闭包.....
//使用Mvvm框架只需添加如下闭包配置便可以了
dataBinding{
enabled true
}
}
3.DataBinding基本使用包括以下内容:
- 单纯的摆脱findviewbyid
- 绑定基本数据类型及String
- 绑定Model数据
- 绑定事件
- 通过静态方法转换数据类型
- 通过运算符操作数据
- 自定义Binding的类名
- 绑定相同Model的操作
- model变量改变自动更新数据
- 绑定List/Map等集合数据
- Observable自动更新
- Databinding与include标签的结合
- DataBinding与RecyclerView的结合
下面开始:
3.1的内容单纯的拜托findViewById的方法来直接绑定View中的控件,其中activity_main中的代码如下;
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--把我们需要展示的布局文件写在layout里面-->
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">
<Button
android:id="@+id/main_button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="单纯的摆脱findViewById" />
</LinearLayout>
</layout>
在MainActivity中如下代码,每行都有注释很好理解
public class MainActivity extends AppCompatActivity {
//ActivityMainBinding是系统自动生成的
private ActivityMainBinding activityMainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
//通过我们获取到的Binding.id就可以直接使用布局中的控件了,如下添加一个按钮的点击事件
activityMainBinding.mainButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "没有findViewById了!", Toast.LENGTH_SHORT).show();
}
});
//这里的SetContentView()方法不在使用了
//setContentView(R.layout.activity_main);
}
}
这里我们通过获取到的Binding对象然后就能直接获取到View中的ID然后进行我们想要的操作就可以了。
3.2绑定基本数据类型及String
效果如图:
下面我们继续修改XML文件如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!--我们需要绑定的基本数据类型-->
<!--name:如同Java中的对象是类似的,自己定义名字-->
<!--type:如同Java中的类型是一样的,如类的概念-->
<variable
name="content"
type="String" />
<variable
name="enabled"
type="boolean" />
</data>
<!--把我们需要展示的布局文件写在layout里面-->
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">
<!--绑定基本数据类型是通过@{数据类型的对象}来进行数据类型的控制显示-->
<Button
android:id="@+id/main_button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="@{enabled}"
android:text="@{content}" />
</LinearLayout>
</layout>
在布局中是通过@{}来绑定数据的,{}中是布局中该控件属性对应的数据类型数据,同时还可以支持运算符运算和静态方法调用和转换,这个后面会介绍的。
下面是MainActivity中的代码:
public class MainActivity extends AppCompatActivity {
//ActivityMainBinding是系统自动生成的
private ActivityMainBinding activityMainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
//绑定基本数据类型
activityMainBinding.setContent("对基本数据类型String进行绑定");
activityMainBinding.setEnabled(true);//这里给控件设置可点击的属性,这里设置false是不可点击
//其实下面的这个绑定事件是不能用的,因为上面一行设置了可点击false属性
//通过我们获取到的Binding.id就可以直接使用布局中的控件了,如下添加一个按钮的点击事件
activityMainBinding.mainButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "其实你点击我是没有用的!", Toast.LENGTH_SHORT).show();
}
});
}
}
这时候点击控件是没有作用效果的额。
3.3绑定Model数据
新建一个JavaBean,取名User只有一个属性用户名。
/**
* Created by AndyYuan on 2019/4/16.
* Created time at 2019/4/16.
*/
public class User {
private String userName;
public User(String userName) {
this.userName = userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
}
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!--我们需要绑定的基本数据类型-->
<!--name:如同Java中的对象是类似的,自己定义名字-->
<!--type:如同Java中的类型是一样的,如类的概念-->
<variable
name="user"
type="com.example.andyyuan.mvvmproject.User" />
</data>
<!--把我们需要展示的布局文件写在layout里面-->
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">
<!--绑定基本数据类型是通过@{数据类型的对象}来进行数据类型的控制显示-->
<Button
android:id="@+id/main_button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.userName}" />
</LinearLayout>
</layout>
对Model中的数据的操作进行如下:
public class MainActivity extends AppCompatActivity {
//ActivityMainBinding是系统自动生成的
private ActivityMainBinding activityMainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
//新建User对象,来进行绑定user对象model数据
final User user = new User("我是user名字被绑定了");
//activityMainBinding.setUser(user);
//绑定数据也可以这样来写
activityMainBinding.setVariable(BR.user,user);
activityMainBinding.mainButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,user.getUserName(),Toast.LENGTH_LONG).show();
}
});
}
}
3.4 绑定事件
效果如下:
下面讲解事件的绑定,这个例子是最简单的事件绑定机制:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<!--我们需要绑定的基本数据类型-->
<!--name:如同Java中的对象是类似的,自己定义名字-->
<!--type:如同Java中的类型是一样的,如类的概念-->
<variable
name="event"
type="com.example.andyyuan.mvvmproject.EventListener" />
<variable
name="button1"
type="String" />
<variable
name="button2"
type="String" />
<variable
name="button3"
type="String" />
</data>
<!--把我们需要展示的布局文件写在layout里面-->
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">
<!--绑定基本数据类型是通过@{数据类型的对象}来进行数据类型的控制显示-->
<Button
android:id="@+id/main_button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{event::onClick1}"
android:text="@{button1}" />
<Button
android:id="@+id/main_button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{event::onClick2}"
android:text="@{button2}" />
<Button
android:id="@+id/main_button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{event::onClick3}"
android:text="@{button3}" />
</LinearLayout>
</layout>
新建接口EventListener如下:
/**
* Created by AndyYuan on 2019/4/16.
* Created time at 2019/4/16.
*/
public interface EventListener {
void onClick1(View view);
void onClick2(View view);
void onClick3(View view);
}
主类中的代码如下:
public class MainActivity extends AppCompatActivity {
//ActivityMainBinding是系统自动生成的
private ActivityMainBinding activityMainBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
activityMainBinding.setButton1("这个是第一个按钮Button1");
activityMainBinding.setButton2("这个是第二个按钮Button2");
activityMainBinding.setButton3("这个是第三个按钮Button3");
activityMainBinding.setEvent(new EventListener() {
@Override
public void onClick1(View view) {
activityMainBinding.setButton1("第一个按钮被点击");
Toast.makeText(MainActivity.this, "点击了第一个按钮", Toast.LENGTH_LONG).show();
}
@Override
public void onClick2(View view) {
activityMainBinding.setButton1("第二个按钮被点击");
Toast.makeText(MainActivity.this, "点击了第二个按钮", Toast.LENGTH_LONG).show();
}
@Override
public void onClick3(View view) {
activityMainBinding.setButton1("第三个按钮被点击");
Toast.makeText(MainActivity.this, "点击了第三个按钮", Toast.LENGTH_LONG).show();
}
});
}
}
3.5 通过静态方法转换数据类型