Databinging
基础入门
- 首先在模块的build.gradle添加databinding支持
android {
...
dataBinding{
enabled = true
}
...
}
- 然后我们新建一个实体:
public class User extends BaseObservable {
private String name;//名字
private String intro;//简介
//getter and setter
}
- 创建布局文件
activity_view_model.xml
:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/tools">
<data>
<variable
name="user"
type="org.zgc.aac.bean.entity.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@{user.name}"
android:textSize="14sp"
bind:text="Name" />
<TextView
android:id="@+id/tv_intro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@{user.intro}"
android:textSize="14sp"
bind:text="Name" />
</LinearLayout>
</layout>
这里要注意一下,最外层是<layout>标签,<layout>标签里面只允许包含一个数据元素(data)和一个布局元素 (别问我为什么,因为这是固定写法)。
数据元素
上面布局中<data>里面使用了<variable>来声明一个变量,属性name定义变量名,属性type定义该变量的引用。
布局元素
这里要注意的一点是布局元素最外局必需是一个ViewGroup,我们先留意一下这里android:text="@{user.intro}"
,然后下面会说到。
- 创建Activity
ViewModelActivity.java
在onCreate方法添加如下代码
@Override
protected void onCreate(Bundle savedInstanceState) {.
super.onCreate(savedInstanceState);
ActivityViewModelBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_view_model);
//创建一个User对象,并添加数据
User user = new User();
user.setName("ZGC");
user.setIntro("这个人很懒,什么也没写!");
//把User对象和布局文件进行绑定了
binding.setUser(user);
}
运行一下看效果:
databinding1.png
可以看到User对象的信息在界面显示出来,并不用手动去设置。
那它的值是如果设置上去的?我们在Activity把数据设置给了布局的user变量( 步骤4代码-->binding.setUser(user);),然后在布局中通过变量user设置到界面上去(比如名字:android:text="@{user.name}"),这就是Datading的基本使用。
还有一个需要注意的,User对象的属性如果是private就必需提供get()方法,在布局中才能访问到,如果是public的就不需要。
单向数据绑定
上面简单说明了Databinding的基础使用方法,现在我们说一下单向数据绑定。
还是上面的例子,如果我们的数据改变了,应该怎样更新界面的数据呢?以前的做法应该是textview.setText(“content");
通过手动去重新设置一次,现在我们使用Databinding就不用那么麻烦了。
- 首先对User对象进行修改,代码如下:
public class User extends BaseObservable {
private String name;//名字
private String intro;//简介
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(org.zgc.aac.BR.name);
}
@Bindable
public String getIntro() {
return intro;
}
public void setIntro(String intro) {
this.intro = intro;
notifyPropertyChanged(org.zgc.aac.BR.intro);
}
}
BaseObservable是什么呢,它可以通过Observable的方式去通知UI数据已经改变了,从需更新界面数据;
使用的3个步骤
- 继承BaseObservable;
- Getter添加注解@Bindable
-
Setter里面调用notifyPropertyChanged
就是这么简单,当数据发生改变的时候,BaseObservable就会自动更新界面的数据。那我们在上面的例子添加一个添加靓仔按钮,点击一次就在名字后面添加"靓仔",关键代码如下:
private StringBuffer sb = new StringBuffer();
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_click:
user.setName(user.getName() + "靓仔");
break;
}
}
运行看一下效果:
device-2019-10-23-223403[00_00_00--00_00_20].gif
可以看到我们改变User对象的属性,界面就会自动更新。
但是如果对象的属性很多,我们要添加的代码量就很大了,所以官方还提供了另一种方法,修改User对象,代码如下:
public class User {
private ObservableField<String> name;//名字
private ObservableField<String> intro;//简介
//getter and setter
}
这样就比较简单了
Databinding为各种类型提供了包装类
8种基础数据的包装类
- ObservableBoolean
- ObservableByte
- ObservableChar
- ObservableDouble
- ObservableFloat
- ObservableInt
- ObservableLong
- ObservableShort
集合的包装类
- ObservableArrayList
- ObservableArrayMap
实现了Parcelable接口对象的包装类
- ObservableParcelable
Object对象的包装类
-
ObservableField(比如上面例子中,使用String对象:
ObservableField<String>
)
双向数据绑定
上面说了单向的数据绑定,那如果我在界面中更改了数据,如果更新到对象中?
继续上面的例子,我们添加一个Editext控件,数据绑定为User.intro:关键代码如下:
<EditText
android:id="@+id/tv_content_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入你的简介"
android:padding="10dp"
android:text="@{user.intro}" />
运行一下看效果:
这时候发现上面的TextView标签的内容并没有更改,其实我们只需要把EditText绑定方式加一个“=”就可以了,代码如下:
<EditText
android:id="@+id/tv_content_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入你的简介"
android:padding="10dp"
android:text="@={user.intro}" />
运行一下看效果:
可以看到,在EditText更改内容后,上面的TextView也自动更改内容了。
事件绑定
在上面单向数据绑定,我们添加了一个按钮,现在我们说一下这个按钮是怎样和控件绑定的。
- 首页先添加一个类,里面有一个onClick(View view)方法(这个名字可自定义),关键代码如下:
public class Action {
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_click:
user.getName().set(user.getName().get() + "靓仔");
break;
}
}
}
- 在布局data元素添加一个variable元素
<variable
name="action"
type="org.zgc.aac.activity.ViewModelActivity.Action" />
- 添加一个按钮,关键代码如下:
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_click"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{action::onClick}"
android:text="click" />
通过android:onClick="@{action::onClick}"
把按钮的单击事件响应绑定到onClick(View view)方法了。
网友评论