數(shù)據(jù)綁定框架DataBinding--入門篇

一坏快、描述

MVC,MVP都是大家所熟知的憎夷,而今天的主題的MVVM數(shù)據(jù)綁定莽鸿,這個是最新推出的框架,剛加入公司沒多久拾给,看公司里的同事再用這個富拗,所以我熟悉之后發(fā)現(xiàn)確實(shí)挺好用的,在這里分享給大家鸣戴。

二、引用

Data Binding自從去年的Google I/O發(fā)布到至今粘拾,也有近一年的時間了窄锅。這一年來,從Beta到如今比較完善的版本,從Android Studio 1.3到如今2.1.2的支持入偷,可以說Data Binding已經(jīng)是一個可用度較高追驴,也能帶來實(shí)際生產(chǎn)力提升的技術(shù)了。

而事實(shí)上疏之,真正使用到Data Binding的公司殿雪、項目仍然是比較少的》孀Γ可能是出于穩(wěn)定性考慮丙曙,亦或是對Data Binding技術(shù)本身不夠熟悉,又或許對新技術(shù)沒什么追求其骄。

我司在新的產(chǎn)品中就全面使用了Data Binding技術(shù)亏镰,無論是我,還是新來直接面對Data Binding上手的工程師也好拯爽,都對其愛不釋手索抓,用慣了后簡直停不下來。

希望在看完本文的介紹后毯炮,會有更多的朋友產(chǎn)生興趣逼肯,來使用Data Binding,參與它的討論桃煎。

三篮幢、什么是DataBinding

這里我以我的理解來說,就是一個或者多個實(shí)體對象對應(yīng)著一個頁面备禀,實(shí)體中的某些屬性綁定著頁面上的控件洲拇,當(dāng)屬性的值改變時,頁面上的控件會自動更新數(shù)據(jù)曲尸。

四赋续、效果展示

沒用DataBinding之前

XML布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    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.example.junwen.databinding.MainActivity">

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="姓名:" />

        <TextView
            android:id="@+id/activity_main_stu_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="學(xué)生姓名" />
    </LinearLayout>

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="年齡:" />

        <TextView
            android:id="@+id/activity_main_stu_age"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text="學(xué)生年齡" />
    </LinearLayout>


    <Button
        android:id="@+id/activity_main_stu_setting"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="更改姓名" />
</LinearLayout>

Student實(shí)體類


/**
 * 描述:學(xué)生對象
 * 作者:卜俊文
 * 創(chuàng)建:2016/8/10 10:20
 * 郵箱:344176791@qq.com
 */
public class Student {
    private String name;
    private int age;

    public Student(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;
    }
}



MainActivity主頁面



public class MainActivity extends AppCompatActivity {

    private TextView tv_name; //學(xué)生姓名
    private TextView tv_age; //學(xué)生年齡
    private Button btn_setting; //設(shè)置
    private Student student; //學(xué)生對象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
        initListener();
    }


    /**
     * 描述:初始化控件
     * 作者:卜俊文
     * 郵箱:344176791@qq.com
     * 創(chuàng)建時間: 2016/8/10 10:17
     */
    private void initView() {
        tv_name = (TextView) findViewById(R.id.activity_main_stu_name);
        tv_age = (TextView) findViewById(R.id.activity_main_stu_age);
        btn_setting = (Button) findViewById(R.id.activity_main_stu_setting);
    }

    /**
     * 描述:初始化數(shù)據(jù)
     * 作者:卜俊文
     * 郵箱:344176791@qq.com
     * 創(chuàng)建時間: 2016/8/10 10:19
     */
    private void initData() {
        //創(chuàng)建一個學(xué)生對象
        student = new Student("俊文", 22);
        //根據(jù)學(xué)生對象賦值到控件上
        tv_name.setText(student.getName());
        tv_age.setText(String.valueOf(student.getAge()));
    }

    /**
     * 描述:初始化監(jiān)聽
     * 作者:卜俊文
     * 郵箱:344176791@qq.com
     * 創(chuàng)建時間: 2016/8/10 10:22
     */
    private void initListener() {
        btn_setting.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //點(diǎn)擊設(shè)置,更改Student對象的名字。
                student.setName("卜俊文");
                tv_name.setText(student.getName());
            }
        });
    }

}


運(yùn)用DataBinding

XML布局

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="student"
            type="com.example.junwen.databinding.Student" />
    </data>

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

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

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:text="姓名:" />

            <TextView
                android:id="@+id/activity_main_stu_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:text="@{student.name}" />
        </LinearLayout>

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

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:text="年齡:" />

            <TextView
                android:id="@+id/activity_main_stu_age"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:text="@{String.valueOf(student.age)}" />
        </LinearLayout>


        <Button
            android:id="@+id/activity_main_stu_setting"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="更改姓名" />
    </LinearLayout>
</layout>  

Student實(shí)體類



/**
 * 描述:學(xué)生對象, @Bindable注解是為了能在BR里面找到這個屬性     notifyPropertyChanged();  這個方法是當(dāng)調(diào)用的時候另患,會通知綁定的控件去改變值
 * 作者:卜俊文
 * 創(chuàng)建:2016/8/10 10:20
 * 郵箱:344176791@qq.com
 */
public class Student extends BaseObservable {

    @Bindable
    private String name;

    @Bindable
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(com.example.junwen.databinding.BR.name);
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
        notifyPropertyChanged(com.example.junwen.databinding.BR.age);
    }
}

MainActivity主頁面



public class MainActivity extends AppCompatActivity {


    private ActivityMainBinding activity_main_binding; //本頁面的Binding對象
    private Student student; //學(xué)生對象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initListener();
    }

    /**
     * 描述:初始化數(shù)據(jù)
     * 作者:卜俊文
     * 郵箱:344176791@qq.com
     * 創(chuàng)建時間: 2016/8/10 10:48
     */
    private void initData() {
        //這個就類似于setContentView
        activity_main_binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        student = new Student("俊文", 22);
        //把Student對象綁定到布局的控件中去,現(xiàn)在開始只要student對象屬性變化纽乱,控件的值也是相應(yīng)改變
        activity_main_binding.setStudent(student);
    }

    /**
     * 描述:初始化監(jiān)聽
     * 作者:卜俊文
     * 郵箱:344176791@qq.com
     * 創(chuàng)建時間: 2016/8/10 10:22
     */
    private void initListener() {
        activity_main_binding.activityMainStuSetting.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                student.setName("卜俊文");
            }
        });
    }

}

五、優(yōu)劣所在昆箕?

優(yōu)勢

(1) DataBinding不需要findviewbyId鸦列,只需要根據(jù)binding對象去查找到對應(yīng)的控件。

(2)直接綁定一個對象到XML布局中鹏倘,當(dāng)對象的屬性變化時薯嗤,布局中的控件會馬上同步變化。

(3)UI代碼放到了xml中纤泵,布局和數(shù)據(jù)更緊密

劣勢

(1)IDE支持還不那么完善(提示骆姐、表達(dá)式)

(2)報錯信息不那么直接

六、開始編寫

(1) 在app / build.gradle 中加入以下字段,即可使用DataBinding框架

dataBinding {   
 enabled = true
}

(2)編寫XML玻褪,這里給出一個XML模版

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="item"
            type="com.example.junwen.databinding.Student" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{item.name}" />
    </LinearLayout>
</layout>  

此模塊由<Layout>標(biāo)簽作為根節(jié)點(diǎn)肉渴,里面包含兩部分,第一部分是<data>,第二部分就是<LinearLayout>带射,也就類似于以前我們寫布局時的根布局同规。

其中<data>標(biāo)簽中可以聲明對象,變量以及導(dǎo)入包等功能窟社,在這里我導(dǎo)入了Student對象券勺,在下面我需要用到我就可以導(dǎo)入進(jìn)來,并且起成item的一個別名桥爽。

其中<LinearLayout>中朱灿,包含了一個TextView,這個TextView的text屬性值是這樣賦值的(格式必須對):

android:text="@{item.name}"

雙引號中 " @{具體變量或者對象的屬性值}" 钠四,不只這些盗扒,還可以在里面運(yùn)用表達(dá)式,例如上面的例子中的

 android:text="@{String.valueOf(student.age)}"

這個能夠在一個屬性的后面添加字符串比如下面

android:text="@{item.progress+`%`}"

(3)編寫MainActivity

(1)取得Binding對象缀去,這個就類似于setContentView()侣灶,返回的對象其實(shí)是一個ViewDataBinding,但是我這里寫的是ActivityMainBinding缕碎,你可以比較一下ActivityMainBinding 和 R.layout.activity_main有什么相似的地方嗎褥影?不錯,就是拼接起來的咏雌,這樣就可以獲得這個頁面的Binding對象凡怎。

ActivityMainBinding activity_main_binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

(2)創(chuàng)建一個Student對象,并且調(diào)用setStudent(student)方法赊抖,這個方法他會自動生成的统倒,實(shí)現(xiàn)了實(shí)體與xml綁定。

Student student = new Student("俊文", 22);
//把Student對象綁定到布局的控件中去,現(xiàn)在開始只要student對象屬性變化氛雪,控件的值也是相應(yīng)改變
activity_main_binding.setStudent(student)

(3)設(shè)置監(jiān)聽房匆,直接通過binding對象查詢到按鈕控件,這個activityMainStuSetting也會自動生成的报亩,如果遇到?jīng)]有生成浴鸿,你需要build一下項目,他就會出來了,執(zhí)行setName方法弦追,在其內(nèi)部就會去通知控件更新文本岳链。

activity_main_binding.activityMainStuSetting.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                student.setName("卜俊文");
            }
        });

七、其他

操作符示例:

(1)判斷屬性賦值不同的圖片

android:src="@{item.checkState.equals(String.valueOf(3)) ? @drawable/ic_task_exit :  @drawable/ic_task_success }" 

(2)設(shè)置不同的字符串

android:text='@{error ? "error" : "ok"}'

XML的DataBinding模版XML快速創(chuàng)建

1229.gif

關(guān)于DataBinding數(shù)據(jù)綁定

Android官方數(shù)據(jù)綁定框架DataBinding

從零開始的Android新項目7 - Data Binding入門篇

Android官方數(shù)據(jù)綁定框架DataBinding(一)

Android Data Binding代碼實(shí)戰(zhàn)

完全掌握Android Data Binding

數(shù)據(jù)綁定DataBinding

八劲件、總結(jié)

在此就總結(jié)了一些基本的DataBind的用法宠页,可能有些地方說的不到位的左胞,也是剛接觸不是很熟悉,就是憑自己的理解來說的举户。

歡迎關(guān)注我的微信公眾號,分享更多技術(shù)文章。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末遍烦,一起剝皮案震驚了整個濱河市俭嘁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌服猪,老刑警劉巖供填,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異罢猪,居然都是意外死亡近她,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門膳帕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粘捎,“玉大人,你說我怎么就攤上這事危彩≡苣ィ” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵汤徽,是天一觀的道長娩缰。 經(jīng)常有香客問我,道長谒府,這世上最難降的妖魔是什么拼坎? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮完疫,結(jié)果婚禮上泰鸡,老公的妹妹穿的比我還像新娘。我一直安慰自己趋惨,他們只是感情好鸟顺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著器虾,像睡著了一般讯嫂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兆沙,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天欧芽,我揣著相機(jī)與錄音,去河邊找鬼葛圃。 笑死千扔,一個胖子當(dāng)著我的面吹牛憎妙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播曲楚,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼厘唾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了龙誊?” 一聲冷哼從身側(cè)響起抚垃,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎趟大,沒想到半個月后鹤树,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逊朽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年罕伯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叽讳。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡追他,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绽榛,到底是詐尸還是另有隱情湿酸,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布灭美,位于F島的核電站推溃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏届腐。R本人自食惡果不足惜铁坎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望犁苏。 院中可真熱鬧硬萍,春花似錦、人聲如沸围详。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽助赞。三九已至买羞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雹食,已是汗流浹背畜普。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留群叶,地道東北人吃挑。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓钝荡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親舶衬。 傳聞我的和親對象是個殘疾皇子埠通,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,867評論 25 707
  • 參考自一葉飄舟 Android新推出了一個官方的數(shù)據(jù)綁定框架Data Binding Library,既然是官方推...
    劉滌生閱讀 6,471評論 4 24
  • 妮兒: 再有十二天你就十一歲了逛犹,媽媽今天才第一次給你寫信植阴! 我如此的渴望有個女兒,卻沒想到我和我的女兒之間能有那么...
    Simple_mw閱讀 510評論 0 2
  • 我們總管不住自己的手圾浅。。憾朴。 VS的啟動時發(fā)生錯誤的對話框點(diǎn)了不再提示后又迅速點(diǎn)了確定狸捕。。 要是不知道怎么恢復(fù)众雷,只能...
    lack倪醬閱讀 1,445評論 0 0
  • 我想你灸拍,在最深的夜里 那里有著我們的過去 我想你,在過去的記憶里 那里還有著你存在的痕跡 可是呀砾省,我現(xiàn)在也只能想想...
    幻夢邪魂閱讀 347評論 0 2