【Android開發(fā)】DataBinding使用

基礎(chǔ)理解

DataBinding針對每個(gè)Activity的布局猾浦,在編譯階段屹电,生成一個(gè)ViewDataBinding類的對象,該對象持有Activity要展示的數(shù)據(jù)和布局中的各個(gè)view的引用(也就解決了findViewById的問題)跃巡,同時(shí)該對象還有將數(shù)據(jù)分解到各個(gè)view危号,在UI線程上更新數(shù)據(jù),監(jiān)控?cái)?shù)據(jù)的變化素邪,實(shí)時(shí)更新等功能外莲,這樣要展示的數(shù)據(jù)和展示它的布局就緊密的聯(lián)系在一起了。

簡單例子

首先我們先建立一個(gè)java bean兔朦。

public class User {
    private String name;
    private String age;

    public User(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getName() {
        return this.name;
    }

    public String getAge() {
        return this.age;
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <variable
            name="user"
            type="app.ylm.com.studyproject.User"/>
    </data>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:text="@{user.name}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:text="@{user.age}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>
</layout>

然后會自動生成Binding類偷线,命名規(guī)則為:
xml通過文件名生成,使用下劃線分割大小寫沽甥,后綴加上Binding声邦。比如activity_demo.xml,則會生成ActivityDemoBinding摆舟。在Activity中使用亥曹。

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DatabindingBinding binding = DataBindingUtil.setContentView(this,R.layout.databinding);
        User user = new User("tony","12");
        binding.setUser(user);
    }
}

這樣就可以使用了


主要組成部分

1肥卡、ViewDataBinding

數(shù)據(jù)綁定類的基類埠帕。
ViewDataBinding的實(shí)例一般是DataBindingUtil調(diào)用setContentView(Activity activity, int layoutId)方法生成。

2仇味、BR

BR中的常量是一種標(biāo)識符照宝,它對應(yīng)一個(gè)會發(fā)生變化的數(shù)據(jù)蛇受,當(dāng)數(shù)據(jù)改變后,你可以用該標(biāo)識符通知DataBinding厕鹃,很快兢仰,DataBinding就會用新的數(shù)據(jù)去更新UI乍丈。

3、DataBindingUtil

可以從layout創(chuàng)建數(shù)據(jù)綁定類把将。

關(guān)于他們之間的關(guān)系可以看這篇
DataBinding實(shí)現(xiàn)原理探析

拓展

變量定義

<layout xmlns:android="http://schemas.android.com/apk/res/android"> 
        <data> 
            <import type="android.graphics.Bitmap" /> 
            <import type="java.util.ArrayList" /> 
            <import type="java.util.HashMap" />  
          <!-- 集合的定義 -->
            <variable 
                name="list" 
                type="ArrayList<String>" /> 
            <variable 
                name="map" 
                type="HashMap<String, String>" /> 
            <variable 
                name="array" 
                type="String[]" /> 
          <!-- 為集合定義對應(yīng)的索引 -->
            <variable 
                name="listKey" 
                type="int" /> 
            <variable 
                name="mapKey" 
                type="String" /> 
            <variable 
                name="arrayKey" 
                type="int" /> 

            <!-- 字符串轻专,布爾值和int的用法-->
            <variable 
                name="str" 
                type="String"/> 
            <variable 
                name="error" 
                type="boolean"/> 
            <variable 
                name="num" 
                type="int" /> 

        </data> 

        <LinearLayout 
            android:orientation="vertical" 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"> 

            <TextView 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:text="@{list[listKey]}"/> 

            <TextView 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:text="@{map[`name`]}"/> 
            <TextView 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:text="@{array[0]}"/> 

            <TextView 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:text="@{str}"/> 
            <TextView 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:text="@{String.valueOf(num)}"/> 
        </LinearLayout> 
    </layout>

事件的綁定

可以直接在 xml 導(dǎo)入android.view.View.OnClickListener,并制定其點(diǎn)擊事件秸弛。

<variable
    name="clickListener"
    type="android.view.View.OnClickListener" />
...
  android:onClick="@{clickListener}"
...
holder.binding.setClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               //do something
        });

表達(dá)式

在xml文件中還是支持表達(dá)式的,比如說如下:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text='@{error ? "yes" : "no"}'/>

支持的表達(dá)式:
Mathematical + - / * %
String concatenation +
Logical && ||
Binary & | ^
Unary + - ! ~
Shift >> >>> <<
Comparison == > < >= <=
instanceof
Grouping ()
Literals - character, String, numeric, null
Cast
Method calls
Field access
Array access []
Ternary operator ?:

使用類方法

比如User中有一個(gè)靜態(tài)方法

public static String getLevel(){
  return "0";
}

然后在 xml 的 data 節(jié)點(diǎn)中導(dǎo)入:

 <import type="app.ylm.com.studyproject.User"/>

使用方法與 Java 語法一樣:

 <TextView
            android:text="@{User.getLevel()}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

Observable Binding

要實(shí)現(xiàn) Observable Binding洪碳,首先得有一個(gè)實(shí)現(xiàn)了 android.databinding.Observable 的類递览,為了方便,Android 原生提供了已經(jīng)封裝好的一個(gè)類 - BaseObservable瞳腌,并且實(shí)現(xiàn)了監(jiān)聽器的注冊機(jī)制绞铃。

public class ObservableUser extends BaseObservable {
    private String firstName;
    private String lastName;
    @Bindable
    public String getFirstName() {
        return firstName;
    }
    @Bindable
    public String getLastName() {
        return lastName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
        notifyPropertyChanged(BR.firstName);
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
        notifyPropertyChanged(BR.lastName);
    }
}

通過代碼可以看出,當(dāng)數(shù)據(jù)發(fā)生變化時(shí)還是需要手動發(fā)出通知嫂侍。 通過調(diào)用notifyPropertyChanged(BR.firstName)來通知系統(tǒng) BR.firstName 這個(gè) entry 的數(shù)據(jù)已經(jīng)發(fā)生變化儿捧,需要更新 UI。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挑宠,一起剝皮案震驚了整個(gè)濱河市菲盾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌各淀,老刑警劉巖懒鉴,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碎浇,居然都是意外死亡临谱,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門奴璃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悉默,“玉大人,你說我怎么就攤上這事苟穆〕危” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵雳旅,是天一觀的道長剖膳。 經(jīng)常有香客問我,道長岭辣,這世上最難降的妖魔是什么吱晒? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮沦童,結(jié)果婚禮上仑濒,老公的妹妹穿的比我還像新娘叹话。我一直安慰自己,他們只是感情好墩瞳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布驼壶。 她就那樣靜靜地躺著,像睡著了一般喉酌。 火紅的嫁衣襯著肌膚如雪热凹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天泪电,我揣著相機(jī)與錄音般妙,去河邊找鬼。 笑死相速,一個(gè)胖子當(dāng)著我的面吹牛碟渺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播突诬,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼苫拍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旺隙?” 一聲冷哼從身側(cè)響起绒极,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔬捷,沒想到半個(gè)月后集峦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抠刺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年塔淤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片速妖。...
    茶點(diǎn)故事閱讀 39,926評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡高蜂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出罕容,到底是詐尸還是另有隱情备恤,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布锦秒,位于F島的核電站露泊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏旅择。R本人自食惡果不足惜惭笑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沉噩,春花似錦捺宗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至畜眨,卻和暖如春昼牛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背康聂。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工贰健, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人早抠。 一個(gè)月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓霎烙,卻偏偏與公主長得像撬讽,于是被迫代替她去往敵國和親蕊连。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容