2015年的GoogleI/O大會(huì)上钠右,Google推出了自己官方的數(shù)據(jù)綁定框架Data Binding Library赋元,雖然網(wǎng)絡(luò)上有很多第三方的數(shù)據(jù)綁定框架,但是飒房,第三方的框架都是別的公司或者團(tuán)隊(duì)在維護(hù)搁凸,有些公司或者團(tuán)隊(duì)看到自己的東西沒有很好的收益或者其他原因,一下子就不在維護(hù)了狠毯,這對(duì)我們來說就是一個(gè)大麻煩护糖,所以,使用官方的框架是我們第一個(gè)選擇嚼松。
在沒有出來這個(gè)以前嫡良,我們獲取控件的句柄一般是通過findViewById或者使用注解,使用注解雖然是不需要我們寫很多的findViewById惜颇,但是大量使用注解會(huì)拖慢我們APP的速度皆刺。但是使用Data Binding就不會(huì),根據(jù)官方文檔的解析凌摄,使用Data Binding還會(huì)提高XML的解析速度羡蛾。Data Binding的推出,解決了Android UI編程的一個(gè)痛點(diǎn)锨亏,是Google官方對(duì)MVVM在Android上的一個(gè)實(shí)現(xiàn)痴怨,我們可以在不改變原有框架的基礎(chǔ)上忙干,使用這些新特性。使用Data Binding可以讓我們開發(fā)中減少很多與UI相關(guān)的代碼浪藻,可以直接將數(shù)據(jù)綁定到XML上捐迫,可以實(shí)現(xiàn)自動(dòng)刷新。
下面開始使用這個(gè)官方的大殺器
1爱葵、開發(fā)環(huán)境
將Android studio更新到最新版本施戴,現(xiàn)在Google也在我大天朝上線了開發(fā)者網(wǎng)站,我們不在需要跨過長城了萌丈,下面提供一下Google在天朝的開發(fā)者網(wǎng)站地址:https://developer.android.google.cn/index.html
更新完Android studio之后赞哗,將Gradle也更新到新的版本,最少不低于1.5.0版本辆雾,我用的是最新的2.2.3版本:
classpath 'com.android.tools.build:gradle:2.2.3'
然后在當(dāng)前model的android{}閉包中添加對(duì)Data Binding的支持:
android {
...
dataBinding {
enabled true
}
}
這樣準(zhǔn)備好了環(huán)境肪笋,下面開始一個(gè)簡單的例子
2、Data Binding簡單例子
在上面的環(huán)境準(zhǔn)備好了之后度迂,我們可以開始編寫代碼:
首先藤乙,我們需要一個(gè)普通的JavaBean,一個(gè)簡單的Student類:
public class Student {
private String name;
private String addr;
public Student() {
}
public Student(String name, String addr) {
this.name = name;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return this.addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
}
這是一個(gè)簡單的JavaBean惭墓,提供相應(yīng)的get和set方法坛梁。
接著是布局文件的編碼:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.databindingdemo.Student"/>
<variable
name="stu"
type="Student"/>
</data>
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
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.databindingdemo.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{stu.name}"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{stu.addr}"/>
</LinearLayout>
</layout>
需要注意的是,根布局不再是以前ViewGroup诅妹,而是一個(gè)Layout罚勾,里面的命名空間不能重復(fù)毅人,比如有android的約束就不能在ViewGroup的根節(jié)點(diǎn)中重復(fù)使用吭狡,否則編譯不過去的。
完成布局代碼之后丈莺,就是Activity的編碼:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding a = DataBindingUtil.setContentView(this, R.layout.activity_main);
a.setStu(new Student("Devin", "廣州"));
}
}
這樣就可以實(shí)現(xiàn)在我們布局中顯示數(shù)據(jù)划煮,最后的結(jié)果是:
這樣我們就可以很簡單地實(shí)現(xiàn)了一個(gè)Data Binding的例子。這樣在Activity中我們就不需要寫很多的代碼缔俄,activity里面也變得非常簡潔明了弛秋。
3、Data Binding入門
上面我們簡單實(shí)現(xiàn)了Data Binding俐载,下面我們詳細(xì)地了解一下蟹略。
首先從布局文件入手,先看一下布局文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.databindingdemo.Student"/>
<variable
name="stu"
type="Student"/>
</data>
<LinearLayout
...
</LinearLayout>
</layout>
布局文件中遏佣,根節(jié)點(diǎn)不再是ViewGroup挖炬,而是layout,layout下面有兩個(gè)節(jié)點(diǎn)状婶,分別是<data>和<LinearLayout>意敛,LinearLayout是一個(gè)ViewGroup馅巷,ViewGroup里面寫我們具體的布局代碼,data里面就是我們綁定的數(shù)據(jù)草姻,下面解析一下data這個(gè)節(jié)點(diǎn)钓猬。
<data>
<import type="com.databindingdemo.Student"/>
<variable
name="stu"
type="Student"/>
</data>
data節(jié)點(diǎn)里面有兩個(gè)節(jié)點(diǎn),分別是import和variable撩独,import就是引入JavaBean對(duì)象敞曹,type的值就是全限定類名。我們可以引入多個(gè)類综膀,當(dāng)引入的類同名的時(shí)候异雁,我們還可以在import中添加一個(gè)類的別名,例如:
<import type="com.example.home.data.User" />
<import type="com.examle.detail.data.User" alias="DetailUser" />
<variable name="user" type="DetailUser" />
這里引入的類名字都是User僧须,我們可以用alias這個(gè)屬性起一個(gè)別名纲刀,用于區(qū)分不同的類,這是import標(biāo)簽担平,下面了解一下variable標(biāo)簽示绊。
其中variable就是我們用來定義變量的,在上面的例子中我們就定義了一個(gè)stu變量暂论,類型就是一個(gè)JavaBean面褐,我們還可以定義List、Map取胎、String等的變量展哭,例如:
<variable
name="list"
type="ArrayList<String>" />
<variable
name="map"
type="HashMap<String, String>" />
等等,然后我們就可以在布局文件中使用這些定義的變量闻蛀,這個(gè)就是variable標(biāo)簽的基本作用匪傍。
這里就是布局文件的基本解析,下面了解一下Activity里面的代碼:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this,
R.layout.activity_main);
mainBinding.setStu(new Student("Devin", "廣州"));
}
這里的代碼非常簡單觉痛,就兩句代碼役衡。下面我們了解一下
DataBindingUtil是layout創(chuàng)建數(shù)據(jù)綁定類,當(dāng)我們使用這個(gè)類并調(diào)用setContentView()方法的時(shí)候薪棒,會(huì)創(chuàng)建一個(gè)ActivityMainBinding對(duì)象手蝎,這個(gè)ActivityMainBinding是Data Binding自動(dòng)生成的,根據(jù)布局文件命名俐芯,比如我們這里的布局文件名是:activity_main棵介,然后生成的就是ActivityMainBinding,這個(gè)類的基類是ViewDataBinding吧史,然后調(diào)用set方法將數(shù)據(jù)注入進(jìn)去邮辽,最后就可以實(shí)現(xiàn)數(shù)據(jù)的展示。
ActivityMainBinding這個(gè)類是自動(dòng)生成,生成的規(guī)則是:
布局文件名首字母大寫逆巍,去掉下劃線及塘,下劃線后面首字母大寫,加上Binding
除了可以這樣直接生成之外锐极,Google還給我提供了自定義Binding類名的方法笙僚,就是在data中加一個(gè)class字段就可以了。
4灵再、Data Binding其他使用
綁定事件
我們通常給Button設(shè)置點(diǎn)擊事件都是通過注解綁定或者setOnClickListener肋层,Data Binding也給我提供了可以綁定事件的方法,下面我們具體實(shí)現(xiàn)一下翎迁。
首先是布局文件的代碼:
<data>
<import type="com.databindingdemo.Student"/>
<import type="com.databindingdemo.OnClickListener"/>
<variable
name="stu"
type="Student"/>
<variable
name="click"
type="OnClickListener"/>
</data>
需要定義一個(gè)OnClickListener類栋猖,這里面是我們的點(diǎn)擊事件:
public class OnClickListener {
public void onClick(View view) {
Toast.makeText(view.getContext(), "綁定了點(diǎn)擊事件", Toast.LENGTH_LONG).show();
}
}
然后在布局文件中使用:
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{click.onClick}"
android:text="綁定點(diǎn)擊事件"/>
最后在activity中做一個(gè)設(shè)置:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this,
R.layout.activity_main);
mainBinding.setStu(new Student("Devin", "廣州"));
mainBinding.setClick(new OnClickListener());
}
這樣就可以實(shí)現(xiàn)點(diǎn)擊事件。
表達(dá)式
Data Binding也支持使用表達(dá)式汪榔,下面是Data Binding的常用表達(dá)式跟JAVA的表達(dá)式差不多
- 數(shù)學(xué)計(jì)算 + / * %
- 字符串連接 +
- 邏輯 && ||
- 二進(jìn)制 & | ^
- 一元 + ! ~
- 位移 >> >>> <<
- 比較 == > < >= <=
- instanceof
- 組 ()
- 字面量 字符蒲拉,字符串,數(shù)字痴腌, null
- 類型轉(zhuǎn)換
- 函數(shù)調(diào)用
- 字段存取
- 數(shù)組存取 []
- 三元運(yùn)算符 ?:
有一個(gè)特殊的就是null合并雌团,例如:
android:text='@{str==null ?? "not null"}'
解析一下:str是否是null,是null的話text的值就是str士聪,否則就是not null里面的值锦援,類似與三目運(yùn)算符。
數(shù)據(jù)刷新
Data Binding給我們提供了內(nèi)容觀察者去刷新數(shù)據(jù)的改變剥悟,這個(gè)跟我們在RecyclerView中設(shè)置Adapter通過調(diào)用notifyDatasetChanged()方法通知UI刷新數(shù)據(jù)一樣灵寺。Google官方給我們提供了非常簡單的一種方式去實(shí)現(xiàn),下面我們了解一下具體的步驟:
JavaBean繼承BaseObservable這個(gè)類
在Getter方法上面添加@Bindable注解
在Setter方法中調(diào)用notifyPropertyChanged(BR.name);
這樣就可以完成了区岗,是不是很簡單略板。我們會(huì)發(fā)現(xiàn),在notifyPropertyChanged()方法中有一個(gè)參數(shù)躏尉,BR蚯根,那么BR是什么呢后众?BR跟R差不多胀糜,保存我們變量的引用地址。
上面就是Data Binding的基本解析蒂誉,當(dāng)然還有其它很多的高級(jí)用法教藻,歡迎大家留言交流!S蚁恰@ǖ獭!