早在2015谷歌 I/O大會(huì)上,就介紹了一個(gè)新的框架DataBinding,從名字就可以看出來(lái)据悔,這是一個(gè)數(shù)據(jù)綁定框架。我們?yōu)槭裁匆褂肈ataBinding渣蜗?1.再也不需要編寫(xiě)findViewById了屠尊,有人會(huì)說(shuō),已經(jīng)有butterknife了耕拷,很好用讼昆。2.更新UI數(shù)據(jù)需切換至UI線程,也有人說(shuō),有rxjava了浸赫。但是DataBinding闰围,不僅僅能解決這2個(gè)問(wèn)題,它的核心優(yōu)勢(shì)在于既峡,它解決了將數(shù)據(jù)分解映射到各個(gè)view的問(wèn)題羡榴。什么個(gè)意思?具體來(lái)說(shuō)运敢,就是針對(duì)每個(gè)Activity或者Fragment的布局校仑,在編譯階段,會(huì)生成一個(gè)ViewDataBinding類(lèi)的對(duì)象传惠,該對(duì)象持有Activity要展示的數(shù)據(jù)和布局中的各個(gè)view的引用迄沫。同時(shí)還有如下優(yōu)勢(shì):將數(shù)據(jù)分解到各個(gè)view、在UI線程上更新數(shù)據(jù)卦方、監(jiān)控?cái)?shù)據(jù)的變化羊瘩,實(shí)時(shí)更新,這樣一來(lái)盼砍,你要展示的數(shù)據(jù)已經(jīng)和展示它的布局緊緊綁定在了一起尘吗。我認(rèn)為這才是DataBinding真正的魅力所在。
下面通過(guò)一個(gè)小例子來(lái)讓大家感受一下DataBinding
1浇坐、在在Module的build.gradle android模塊中添加如下配置
android {
dataBinding {
enabled = true
}
}
2睬捶、創(chuàng)建一個(gè)簡(jiǎn)單的JavaBean對(duì)象,姑且就叫UserBean吧
public class UserBean {
private String name; //姓名
private int age; //年齡
public UserBean(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
3近刘、使用了DataBinding之后的Activity的布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.zx.databindingdemo.bean.UserBean" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}" />
<!--注意:這里age是int類(lèi)型侧戴,必須轉(zhuǎn)化為String,否則會(huì)運(yùn)行時(shí)異常-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(user.age)}" />
</LinearLayout>
</layout>
這里和以前使用的xml不同跌宛,根節(jié)點(diǎn)變成了layout酗宋,里面包括了data節(jié)點(diǎn)和傳統(tǒng)的布局。這里的data節(jié)點(diǎn)作用是連接 View 和 Modle 的橋梁疆拘。在這個(gè)data節(jié)點(diǎn)中聲明一個(gè)variable變量蜕猫,那值就可以輕松傳到布局文件中來(lái)了。而且TextView中沒(méi)有給控件定義id哎迄,而是在text的時(shí)候用了@{ }的方法回右,在括號(hào)里面直接引用UserBean對(duì)象的屬性即可完成賦值。
4漱挚、MainActivity
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
UserBean userBean = new UserBean ("張三", "25");
binding.setUser(userBean );
}
}
這個(gè)activity很簡(jiǎn)潔翔烁,沒(méi)有了沒(méi)有了控件的初始化的findViewById或者butterknife的那一堆注解,也沒(méi)有了TextView的setText(),也就2行代碼而已旨涝。大家應(yīng)該已經(jīng)看見(jiàn)了蹬屹,這里用DataBindingUtil.setContentView代替了setContentView,然后創(chuàng)建一個(gè) UserBean 對(duì)象,通過(guò) binding.setUser(userBean) 與 variable 進(jìn)行綁定慨默。注意:這個(gè)ActivityMainBinding 是如何生成的呢贩耐?他是繼承ViewDataBinding,這個(gè)類(lèi)的生成是有規(guī)則的厦取,它是根據(jù)對(duì)應(yīng)的布局文件的名字生成的潮太,比如:activity_main-->ActivityMainBinding 、fragment-->FragmentBinding即:第一個(gè)單詞首字母大寫(xiě)虾攻,第二個(gè)單詞首字母大寫(xiě)铡买,最后都會(huì)拼上Binding就是生成的Binding類(lèi)。
運(yùn)行結(jié)果
看到這里霎箍,估計(jì)也應(yīng)該有人被他的簡(jiǎn)潔吸引了吧寻狂。下面對(duì)可能產(chǎn)生的疑惑進(jìn)行解釋
1. 為什么配置了 dataBinding{enabled = true}之后就可以使用dataBinding方式進(jìn)行開(kāi)發(fā)了?
Android Studio中是依靠gradle來(lái)管理項(xiàng)目的朋沮,在創(chuàng)建一個(gè)項(xiàng)目時(shí),從開(kāi)始創(chuàng)建一直到創(chuàng)建完畢缀壤,整個(gè)過(guò)程是需要執(zhí)行很多個(gè)gradle task的樊拓,這些task有很多是系統(tǒng)預(yù)先幫我們定義好的,比如build task塘慕,clean task等筋夏,DataBinding相關(guān)的task也是系統(tǒng)預(yù)先幫我們定義好的,但是默認(rèn)情況下图呢,DataBinding相關(guān)的task在task列表中是沒(méi)有的条篷,因?yàn)槲覀儧](méi)有開(kāi)啟dataBinding,但是一旦我們通過(guò) dataBinding{enabled = true}的方式開(kāi)啟DataBinding之后,DataBinding相關(guān)的task就會(huì)出現(xiàn)在task列表中蛤织,每當(dāng)我們執(zhí)行編譯之類(lèi)的操作時(shí)赴叹,就會(huì)執(zhí)行這些dataBinding Task, 這些task的作用就是檢查并生成相關(guān)dataBinding代碼,比如dataBindingExportBuildInfoDebug這個(gè)task就是用來(lái)導(dǎo)出debug模式下的build信息的指蚜。
2. ActivityMainBinding這個(gè)類(lèi)從哪來(lái)的乞巧?
通過(guò)第一個(gè)問(wèn)題的解釋?zhuān)覀円簿椭懒薃ctivityMainBinding這個(gè)類(lèi)其實(shí)是系統(tǒng)幫我們自動(dòng)生成的。
但是如果你在實(shí)際編寫(xiě)代碼的過(guò)程中摊鸡,你會(huì)發(fā)現(xiàn)并沒(méi)有執(zhí)行編譯绽媒、運(yùn)行之類(lèi)等操作,ActivityMainBinding這個(gè)類(lèi)就直接能用了免猾,竟然還有這種操作是辕?其實(shí)是Android Studio 這個(gè)IDE自動(dòng)幫我們做了這一步,在默認(rèn)情況下猎提,系統(tǒng)會(huì)使用Android Studio為我們自動(dòng)生成databinding相關(guān)的代碼获三,但是這種方式生成的代碼不能調(diào)試,如果你想通過(guò)點(diǎn)擊ActivityMainBinding跳轉(zhuǎn)到它的源碼中,你會(huì)發(fā)現(xiàn)并不能如你所愿石窑,而是會(huì)跳轉(zhuǎn)到對(duì)應(yīng)的布局文件中牌芋。那么如果我們確實(shí)要查看ActivityMainBinding的源碼并且還想調(diào)試,我們就需要通過(guò)另外一種方式:手動(dòng)編譯代碼松逊。這兩種方式可以通過(guò)Android Studio的設(shè)置面板修改躺屁。
3.DataBinding與ButterKnife的區(qū)別
ButterKnife很多人都用過(guò),在以前的findViewById的時(shí)代经宏,我們厭煩了寫(xiě)這些重復(fù)的代碼犀暑,當(dāng)有了ButterKnife之后,我們采用注解的方式來(lái)查找控件和注冊(cè)監(jiān)聽(tīng)烁兰,配合ButterKnife的插件耐亏,大大提升了我們的開(kāi)發(fā)效率,一度成為開(kāi)發(fā)神器沪斟,但是有了DataBinding之后广辰,你會(huì)發(fā)現(xiàn)使用ButterKnife開(kāi)發(fā)還是不夠簡(jiǎn)潔:比如你需要給很多TextView setText()要獲取editText的內(nèi)容前必須要獲取editText對(duì)象,給view設(shè)置監(jiān)聽(tīng)前也必須要獲取這個(gè)view對(duì)象等等主之。但是使用了DataBinding之后择吊,這些冗余的代碼統(tǒng)統(tǒng)都可以得到簡(jiǎn)化,從而真正的只需要專(zhuān)注于你的業(yè)務(wù)邏輯的處理即可槽奕。
今天只是初識(shí)DataBinding几睛,接下來(lái)會(huì)出一個(gè)系列來(lái)講解它的真正運(yùn)用,希望大家持續(xù)關(guān)注粤攒。
感謝
aspect-oriented-programming-in-android
翻譯 Android中的AOP編程 Android 開(kāi)發(fā)中使用 AOP
深入理解Android之AOP Android基于AOP的非侵入式監(jiān)控之——AspectJ實(shí)戰(zhàn)
精通 Android Data Binding
歡迎學(xué)習(xí)交流這個(gè)系列的文章
DataBinding系列(二):DataBinding的基本用法
DataBinding系列(三):RecyclerView中使用DataBinding
DataBinding系列(四):DataBinding進(jìn)階之路