一.基础使用
1.Gradle依赖
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.wjn.okhttpmvpdemo"
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
即 添加
dataBinding {
enabled = true
}
2.代码说明
实体类
package com.wjn.okhttpmvpdemo.databinding;
public class Student {
private String name;
private String age;
private String sex;
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="stu"
type="com.wjn.okhttpmvpdemo.databinding.Student" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{stu.name}" />
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{stu.age}" />
</LinearLayout>
</layout>
说明
<1> 关于布局文件名
布局文件名很重要,因为它关乎自动生成的Binding java类名。
比如布局文件名为:activity_data_binding 则自动生成的java类为:ActivityDataBindingBinding。
比如布局文件名为:activity_user_list 则自动生成的java类为:ActivityUserListBinding。
即:布局名 驼峰规则+Binding。
且根布局不可设置其他值
<layout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</layout>
只能是
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<2> 关于布局标签
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="stu"
type="com.wjn.okhttpmvpdemo.databinding.Student" />
</data>
...
</layout>
(1) 布局根布局需要修改成<layout></layout>。
(2) <data> <variable/> </data> 格式固定。
(3) 最内层标签 name:对应的属性即Java声明的变量。比如 Student student = new Student(); 其实就是一个变量名。type:对应的属性即Java类的全路径。相当于import 包。如果类比较多 还可以
<data>
<import type="com.wjn.okhttpmvpdemo.databinding.Student" />
<variable
name="stu"
type="Student" />
</data>
即:import type="com.wjn.okhttpmvpdemo.databinding.Student"
<3> 需要先在布局中声明,然后才会在相应的Activity中自动生成XXXBinding类。
Activity使用
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.wjn.okhttpmvpdemo.R;
public class DataBindingActivity extends AppCompatActivity {
private ActivityDataBindingBinding mDataBindingBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDataBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
initView();
}
/**
* 初始化View
*/
private void initView() {
Student student = new Student();
student.setName("张三");
student.setSex("男");
student.setAge("29");
mDataBindingBinding.setStu(student);
}
}
ActivityDataBindingBinding 就是自动生成的XXXBinding类。
设置布局使用
mDataBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
结果
二.绑定多种变量
布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="student"
type="com.wjn.okhttpmvpdemo.databinding.Student" />
<variable
name="stringValue"
type="String" />
<variable
name="boobleValue"
type="boolean" />
<variable
name="intValue"
type="int" />
<variable
name="floatValue"
type="float" />
<variable
name="arrayValue"
type="String[]" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{student.name}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{student.age}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{stringValue}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{String.valueOf(boobleValue)}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{String.valueOf(intValue)}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{String.valueOf(floatValue)}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{arrayValue[0]}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
</LinearLayout>
</layout>
Activity使用
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.wjn.okhttpmvpdemo.R;
public class MoreActivity extends AppCompatActivity {
private ActivityMoreBinding mActivityMoreBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityMoreBinding = DataBindingUtil.setContentView(this, R.layout.activity_more);
initView();
}
/**
* 初始化View
*/
private void initView() {
Student student = new Student();
student.setName("张三");
student.setSex("男");
student.setAge("29");
mActivityMoreBinding.setStudent(student);//对应布局 student
mActivityMoreBinding.setStringValue("字符串");//对应布局 stringValue
mActivityMoreBinding.setBoobleValue(true);//对应布局 boobleValue
mActivityMoreBinding.setIntValue(12);//对应布局 intValue
mActivityMoreBinding.setFloatValue(12.12f);//对应布局 floatValue
String string[] = new String[]{"数组0下标对应值", "数组1下标对应值", "数组2下标对应值"};
mActivityMoreBinding.setArrayValue(string);//对应布局 arrayValue
}
}
结果
三.绑定点击事件
布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="stu"
type="com.wjn.okhttpmvpdemo.databinding.Student" />
<variable
name="setTextViewOnClick"
type="com.wjn.okhttpmvpdemo.databinding.DataBindingActivity" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center"
android:gravity="center"
android:onClick="@{setTextViewOnClick.onTextViewClick}"
android:text="@{stu.name}" />
<TextView
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{stu.age}" />
</LinearLayout>
</layout>
说明
<variable
name="setTextViewOnClick"
type="com.wjn.okhttpmvpdemo.databinding.DataBindingActivity" />
<1> name:自定义,可以任意值。设置监听时set+name值。
<2> type:Activity类所在的全路径。
android:onClick="@{setTextViewOnClick.onTextViewClick}"
<1> setTextViewOnClick:布局文件中的name值。
<2> onTextViewClick:Activity定义的点击事件方法。
Activity使用
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.wjn.okhttpmvpdemo.R;
public class DataBindingActivity extends AppCompatActivity {
private ActivityDataBindingBinding mDataBindingBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDataBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
initView();
}
/**
* 初始化View
*/
private void initView() {
Student student = new Student();
student.setName("张三");
student.setSex("男");
student.setAge("29");
mDataBindingBinding.setStu(student);
//设置点击事件
mDataBindingBinding.setSetTextViewOnClick(this);
}
/**
* 点击事件
*/
public void onTextViewClick(View view) {
Student student = new Student();
student.setName("张三222");
student.setSex("男222");
student.setAge("29222");
mDataBindingBinding.setStu(student);
String name = mDataBindingBinding.getStu().getName();
Log.d("TAG", "获取姓名:" + name);
}
}
说明
//设置点击事件
mDataBindingBinding.setSetTextViewOnClick(this);
setXXX:XXX取值:布局文件中的name值
/**
* 点击事件
*/
public void onTextViewClick(View view) {
Student student = new Student();
student.setName("张三222");
student.setSex("男222");
student.setAge("29222");
mDataBindingBinding.setStu(student);
String name = mDataBindingBinding.getStu().getName();
Log.d("TAG", "获取姓名:" + name);
}
onTextViewClick:布局文件中@{setTextViewOnClick.onTextViewClick} 后面的值
结果
D/TAG: 获取姓名:张三222
四.绑定表达式
布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="myBoolean"
type="com.wjn.okhttpmvpdemo.databinding.BooleanBean" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text='@{myBoolean.isDay ? "Day" : "NotDay"}' />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text='@{myBoolean.isMan ? "Man" : "WoMan"}' />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text='@{myBoolean.isSuccess ? "Successed" : "Failed"}' />
</LinearLayout>
</layout>
实体类
package com.wjn.okhttpmvpdemo.databinding;
public class BooleanBean {
public boolean isMan;
public boolean isSuccess;
public boolean isDay;
public boolean isMan() {
return isMan;
}
public void setMan(boolean man) {
isMan = man;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean success) {
isSuccess = success;
}
public boolean isDay() {
return isDay;
}
public void setDay(boolean day) {
isDay = day;
}
}
Activity调用
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.wjn.okhttpmvpdemo.R;
public class DataBindingActivity extends AppCompatActivity {
private ActivityDataBindingBinding mDataBindingBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDataBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
initView();
}
/**
* 初始化View
*/
private void initView() {
BooleanBean booleanBean = new BooleanBean();
booleanBean.setDay(false);
booleanBean.setMan(false);
booleanBean.setSuccess(true);
mDataBindingBinding.setMyBoolean(booleanBean);
}
}
说明
如果上面表达式有中文时不能编译通过。可能是Java环境的问题,在系统环境变量中增加一个变量,变量名为: JAVA_TOOL_OPTIONS, 变量值为:-Dfile.encoding=UTF-8,保存。要重启一次电脑,中文就解决了。
可使用的表达式
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
Data Binding Library 使用别名
假如我们import了两个相同名称的类。使用下面 “别名”方式区分
...
<data>
<import type="xxx.Name" alias="MyName">
<import type="xxx.xx.Name">
</data>
<TextView xxx:@{MyName.getName()}>
<TextView xxx:@{Name.getName()}>
...
五.设置View显示隐藏
布局文件
<data>
<variable
name="XXXBean"
type="com.XXX.XXXBean" />
<import type="android.view.View" />
</data>
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="52dp"
android:layout_marginLeft="18dp"
android:layout_marginTop="102dp"
android:layout_marginRight="18dp"
android:scaleType="fitXY"
android:src="@drawable/"
android:visibility="@{XXXBean.isGone?View.GONE:View.VISIBLE}">
</ImageView>
即data标签引入
<import type="android.view.View" />
然后
android:visibility="@{XXXBean.isGone?View.GONE:View.VISIBLE}"
六.数据改变
DataBinding使用时,如果数据发生改变。怎么更新Xml布局中的内容呢?下面讲。
1.BaseObservable监听数据改变
步骤
<1> 实体类中 要继承BaseObservale。
<2> 实体类中 getXXX方法上使用注解@Bindable。
<3> 实体类中 setXXX方法里调用方法notifyPropertyChanged。
实体类
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
public class People extends BaseObservable {
private int fieldId = 10;
private String name;
private String age;
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(fieldId);
}
@Bindable
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
notifyPropertyChanged(fieldId);
}
}
Activity使用
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.wjn.okhttpmvpdemo.R;
public class DataBindingActivity extends AppCompatActivity {
private ActivityDataBindingBinding mDataBindingBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDataBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
initView();
}
/**
* 初始化View
*/
private void initView() {
People people = new People();
people.setName("张三");
people.setAge("20");
mDataBindingBinding.setPeople(people);
Log.d("TAG", "默认Name:" + mDataBindingBinding.getPeople().getName());
//设置点击事件
mDataBindingBinding.setSetTextViewOnClick(this);
}
/**
* 点击事件
*/
public void onTextViewClick(View view) {
People people = new People();
people.setName("张三 点击");
people.setAge("40");
mDataBindingBinding.setPeople(people);
Log.d("TAG", "改变后Name:" + mDataBindingBinding.getPeople().getName());
}
}
结果
默认
D/TAG: 默认Name:张三
点击
D/TAG: 改变后Name:张三 点击
2.其他BaseObservable
ObservableField:对应实体类中 String类型。
ObservableBoolean :对应实体类中 boolean类型。
ObservableByte:对应实体类中 byte类型。
ObservableChar:对应实体类中 Char类型。
ObservableShort:对应实体类中 Short类型。
ObservableInt:对应实体类中 Int类型。
ObservableLong:对应实体类中 Long类型。
ObservableFloat:对应实体类中 Float类型。
ObservableDouble:对应实体类中 Double类型。
ObservableParcelable:对应实体类 序列化。
ObservableArrayMap:对应Map。
ObservableArrayList:对应集合。
3.常量使用举例
实体类
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.ObservableBoolean;
import android.databinding.ObservableDouble;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;
public class WoMan {
public ObservableField<String> name = new ObservableField<>();//String类型
public ObservableInt age = new ObservableInt();//Int类型
public ObservableDouble monty = new ObservableDouble();//Double类型
public ObservableBoolean isWoMan = new ObservableBoolean();//布尔类型
}
布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="woman"
type="com.wjn.okhttpmvpdemo.databinding.WoMan" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{woman.name}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{String.valueOf(woman.age)}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text='@{woman.isWoMan ? "women" : "man"}' />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{String.valueOf(woman.monty)}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
</LinearLayout>
</layout>
Activity使用
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.wjn.okhttpmvpdemo.R;
public class DataBindingActivity extends AppCompatActivity {
private ActivityDataBindingBinding mDataBindingBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDataBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
initView();
}
/**
* 初始化View
*/
private void initView() {
WoMan woMan = new WoMan();
woMan.name.set("小红");
woMan.age.set(22);
woMan.isWoMan.set(true);
woMan.monty.set(11111.50d);
mDataBindingBinding.setWoman(woMan);
}
}
4.Map&集合使用举例
布局
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="map"
type="android.databinding.ObservableArrayMap<String,String>" />
<variable
name="list"
type="android.databinding.ObservableArrayList<String>" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{list[0]}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{list[1]}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{map[`name`]}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center"
android:gravity="center"
android:text="@{map[`names`]}" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#CCCCCC" />
</LinearLayout>
</layout>
Activity调用
package com.wjn.okhttpmvpdemo.databinding;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.databinding.ObservableArrayMap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.wjn.okhttpmvpdemo.R;
public class DataBindingActivity extends AppCompatActivity {
private ActivityDataBindingBinding mDataBindingBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDataBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
initView();
}
/**
* 初始化View
*/
private void initView() {
ObservableArrayList<String> list = new ObservableArrayList<>();
ObservableArrayMap<String, String> map = new ObservableArrayMap<>();
list.add("韦德");
list.add("詹姆斯");
map.put("name", "鲁能泰山一队");
map.put("names", "鲁能泰山预备队");
mDataBindingBinding.setList(list);
mDataBindingBinding.setMap(map);
}
}
说明
<variable
name="map"
type="android.databinding.ObservableArrayMap<String,String>" />
<variable
name="list"
type="android.databinding.ObservableArrayList<String>" />
Map&集合使用时 type:ObservableArrayMap&ObservableArrayList的全路径
附:Data Binding Library官方链接
https://developer.android.google.cn/topic/libraries/data-binding/