在我的上篇文章中,简单学习了DataBinding的环境配置和基本使用:
Android DataBinding使用总结(一)
本文将谷歌官方文档中基本使用方式都进行总结使用,
/**
* Created by QingMei on 2017/5/21 21:31
* email:[email protected]
* desc:Used to
*/
public class Student{
public Student(String name, int age) {
this.name.set(name);
this.age = age;
}
public int age;
public String name ;
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="student"
type="com.mei_husky.samplemvvm.model.Student" />
<variable
name="presenter"
type="com.mei_husky.samplemvvm.view.activity.DataBindingBaseActivity.Presenter" />
<import
alias="Utils"
type="com.mei_husky.samplemvvm.util.MyUtils" />
<import type="java.util.List" />
data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mei_husky.samplemvvm.view.activity.DataBindingBaseActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onNameClick(student.name)}"
android:text="@{`Student FirstName :` + student.name}"
android:textAllCaps="false"
android:textSize="14sp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onAgeClick(Utils.addAge(student.age))}"
android:text="@{`Student 年龄 :` + student.age}"
android:textAllCaps="false"
android:textSize="14sp" />
LinearLayout>
layout>
public class DataBindingBaseActivity extends AppCompatActivity {
private ActivityDataBindingBaseBinding binding;
private Student student;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inject();
}
private void inject() {
binding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding_base);
student = new Student("qingMei2", 12);
contents.add("content -> 0");
contents.add("content -> 1");
// 以下两种方式 给XML中 student 赋值
// binding.setStudent(student);
binding.setVariable(BR.student, student);
}
public class Presenter {
public void onNameClick(String Name) {
Toast.makeText(DataBindingBaseActivity.this, Name, Toast.LENGTH_SHORT).show();
}
public void onAgeClick(int age) {
Toast.makeText(DataBindingBaseActivity.this, String.valueOf(age), Toast.LENGTH_SHORT).show();
}
}
}
<import
alias="Utils" //别名
type="com.mei_husky.samplemvvm.util.MyUtils" />
<import type="java.util.List" />
include标签常用于可复用的layout,我们当然也可以通过dataBinding进行数据绑定,首先创建include标签
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="studentInner"
type="com.mei_husky.samplemvvm.model.Student" />
data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:gravity="center"
android:text="@{`include 显示StudentName :` + studentInner.name}"
android:layout_height="wrap_content" />
LinearLayout>
layout>
然后在xml中使用include标签,将student传给include中的studentInner标签:
"@layout/include_bind_views"
bind:studentInner="@{student}" />
Common Features
The expression language looks a lot like a Java expression. These are the same:
Mathematical + - / * %
String concatenation +
Logical && ||
Binary & | ^
Unary + - ! ~
Shift >> >>> <<
Comparison == > < >= <=
instanceof
Grouping ()
Literals - character, String, numeric, null
Cast
Method calls
Field access
Array access []
Ternary operator ?:
比如:
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
this
super
new
Explicit generic invocation(显示泛型调用)
但我们可以通过转义使用泛型:
<variable
name="contents"
type="List<String>" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text='@{"list :"+contents[0]}' />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@{`引用资源文件 appName -> ` + @string/app_name}" />
现在加深一下dataBinding中对Bean的使用,从而实现动态绑定,当数据源改变,UI中对应数据同时改变:
首先是Student的类:
//首先继承 BaseObservale类
public class Student extends BaseObservable{
public Student(String name, int age) {
this.name.set(name);
this.age = age;
}
/**
* ObservableObject 实现数据绑定
* 这里最好是private,否则在xml的代码提示会有两个age(1,成员变量的直接引用 2,代码模板生成),虽然都能用,但强迫症不能忍
*/
private int age;
@Bindable
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
/**
* ObservableFields 实现数据绑定(推荐)
*/
public final ObservableField name = new ObservableField<>();
}
一个实现可见接口的类,允许把监听器和对象绑定,以便监听该对象的所有属性的变化。
可见接口有添加和删除侦听器的机制,但数据改变的通知机制取决于开发者。为了使开发更简洁,创建一个基类(BaseObservable)来实现监听器注册机制。当属性改变时,数据实现类仍负责告知机制,其中getter方法加@Bindable注释,并在setter方法中告知属性的变化。
在编译过程中,绑定注释在BR类文件中生成一个条目,然后在模块包中生成BR类文件。如果数据类的基类不可改变,可以使用方便PropertyChangeRegistry有效地存储和通知侦听器的方式来实现可见接口。
除了这种方式,我们还可以通过ObservableFields实现:
创建可见类的过程中,开发人员想节省时间或有很多属性时可以使用可见字段,例如一些常用的可见类型字段:ObservableBoolean, ObservableByte, ObservableChar,ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, andObservableParcelable。
可见字段是有独立字段的可见对象。原始版本在访问操作中避免装箱和拆箱操作。为方便使用,在数据类创建使用public final修饰的字段。
private static class User {
public final ObservableField firstName =
new ObservableField<>();
public final ObservableField lastName =
new ObservableField<>();
public final ObservableInt age = new ObservableInt();
}
//通过setter和getter方法获取值
user.firstName.set("Google");
int age = user.age.get();
一些应用程序使用更多的动态结构来保存数据。可见集合支持键控存取方式访问这些数据对象。当键是一个像字符串这样的引用类型时,可使用ObservableArrayMap。
1.Student类
//首先继承 BaseObservale类
public class Student extends BaseObservable{
public Student(String name, int age) {
this.name.set(name);
this.age = age;
}
/**
* ObservableObject 实现数据绑定
* 这里最好是private,否则在xml的代码提示会有两个age(1,成员变量的直接引用 2,代码模板生成),虽然都能用,但强迫症不能忍
*/
private int age;
@Bindable
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
/**
* ObservableFields 实现数据绑定
*/
public final ObservableField name = new ObservableField<>();
}
2、在Activity中:
public class DataBindingBaseActivity extends AppCompatActivity {
private ActivityDataBindingBaseBinding binding;
private Student student;
private List contents = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inject();
}
private void inject() {
binding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding_base);
student = new Student("qingMei2", 12);
contents.add("content -> 0");
contents.add("content -> 1");
// 以下两种方式 给XML中 student 赋值
// binding.setStudent(student);
binding.setVariable(BR.student, student);
binding.setPresenter(new Presenter());
binding.setContents(contents);
}
public class Presenter {
public void onNameClick(String Name) {
Toast.makeText(DataBindingBaseActivity.this, Name, Toast.LENGTH_SHORT).show();
}
public void onAgeClick(int age) {
Toast.makeText(DataBindingBaseActivity.this, String.valueOf(age), Toast.LENGTH_SHORT).show();
}
/**
* 监听器和对象绑定 ,详情请查看Student类
* {@link Student}
*/
//ObserableObject 实现动态更新数据
public void onAgeAdd3() {
student.setAge(student.getAge() + 3);
}
//ObservableField 实现动态更新数据(更清晰明了)
public void onNameAppendPoint() {
student.name.set(student.name.get() + ".");
}
// Observable Collections
public ObservableArrayMap datas = new ObservableArrayMap<>();
{
datas.put("string", "我是字符串");
datas.put("int", 1000);
datas.put("student", student);
}
}
}
3、layout文件
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="student"
type="com.mei_husky.samplemvvm.model.Student" />
<variable
name="presenter"
type="com.mei_husky.samplemvvm.view.activity.DataBindingBaseActivity.Presenter" />
<variable
name="contents"
type="List<String>" />
<import
alias="Utils"
type="com.mei_husky.samplemvvm.util.MyUtils" />
<import type="java.util.List" />
data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mei_husky.samplemvvm.view.activity.DataBindingBaseActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onNameClick(student.name)}"
android:text="@{`Student FirstName :` + student.name}"
android:textAllCaps="false"
android:textSize="14sp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onAgeClick(Utils.addAge(student.age))}"
android:text="@{`Student 年龄 :` + student.age}"
android:textAllCaps="false"
android:textSize="14sp" />
<include
layout="@layout/include_bind_views"
bind:studentInner="@{student}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text='@{"list :"+contents[0]}' />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@{`引用资源文件 appName -> ` + @string/app_name}" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onAgeAdd3()}"
android:text="@{`ObservableObjects绑定 age+3`}"
android:textAllCaps="false"
android:textSize="14sp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onNameAppendPoint()}"
android:text="@{`ObservableField绑定 name + 「.」`}"
android:textAllCaps="false"
android:textSize="14sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@{`ObservableMap,String =` + presenter.datas[`string`]}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@{`ObservableMap,int =` + presenter.datas[`int`]}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@{`ObservableMap,Student =` + presenter.datas[`student`]}" />
LinearLayout>
layout>
本文为DataBinding的学习总结,相对内容较多一些,但都很好理解。
我的其它文章:
Android DataBinding使用总结(三)列表展示
Android MVVM+DataBinding结合Dagger2进行开发
Android 神兵利器Dagger2使用详解(一)基础使用
参考文档:
DataBinding 谷歌官方文档
没有的用户可以看这篇:
Data Binding Guide——google官方文档翻译
本文中所有代码都已托管在GitHub上面:
Github传送门,点我查看源码
该demo包含本文中所有代码但不仅限于:
-DataBinding的入门使用以及引导界面
-Databinding的所有基本使用方法
-RecyclerView中使用dataBinding进行列表展示
-RecyclerView中使用dataBinding展示多类型列表