Data Binding的學習與基本使用

當第一次看到Data Binding的時候,我就深深的被它吸引了。

因爲它可以讓數據直接與xml佈局綁定,不用再去寫繁瑣的初始化查找控件再去給其賦值,省去了重複代碼的體力活,提高了我們開發的效率。

經過一番學習,現在把一些基本的使用方法分享出來,希望能幫助想要學習的小夥伴。

學習的前提是你的 android studio 版本要高於等於1.3.0 。在它以下AS是不支持的。不過1.3.0現在應該不會有什麼人使用了吧。

先來說說配置,在你的模塊的 build.gradle 文件中的 android 節點裏添加 dataBinding 配置:

dataBinding {
    enabled = true
}

 

data binding 主要就是在xml佈局裏面的語法使用,在使用它的佈局裏面,起始根標籤是layout,然後下來一個data元素以及一個view根元素,這個view元素就是原來沒有使用 data binding 的佈局裏的根元素。

 

1.  activity_main佈局。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="bean"
            type="com.example.weioule.databindingdemo.Bean"/>
    </data>

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginTop="25dp"
            android:text="@{bean.name}"
            android:textSize="15sp"/>

        <TextView
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="25dp"
            android:layout_marginRight="25dp"
            android:padding="10dp"
            android:text="do next"/>
    </RelativeLayout>
</layout>

像上面的activity_main佈局中,xmlns:android的命名空間你可以寫在layout跟佈局裏也可以寫在下面的View元素的跟佈局裏。

data元素裏的variable標籤就是我們所要綁定的數據,name可以自己定義,type就得指向你的Bean類了,用包名點類名的形式。

在data中可以有多個variable數據 ,其數據類型也可以是任意類型。

當我們在MainActivity裏獲取到data dinding對象把Bean的實例給設置進來時,這裏的bean就有值了。設置的方法爲你set拼接上你的name的名字首字母大寫,類似我們所寫的set方法,我們這裏是setBean()。

定義好數據後,在下面就可以使用了,看我們的第一個TextView的文本設置,引用的就是我們的Bean數據裏的name屬性,它的寫法爲 @{bean.name} 。

來看看我們的MainActivity裏是怎麼與xml進行綁定的:

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setBean(new Bean("垚鑫"));

原來的 setContentView() 替換成了 DataBindingUtil.setContentView(),填充佈局後返回一個 ViewDataBinding 的子類對象 binding,它的類名是可以由你自己命名的,這裏我們沒有定義就使用默認的名字。

命名規則是,xml文件的名字去掉下劃線,後面加上Binding,採用駝峯法命名。這裏呢我們的就是 ActivityMainBinding 了。

這樣綁定後佈局裏所有的控件的id都可以直接獲取,不必再使用 findViewById ,就像MainActivity裏的btn一樣直接使用

binding.btn.setOnClickListener(new View.OnClickListener() {
    ....
});

綁定後通過 binding 給xml裏設置數據 binding.setBean(new Bean("垚鑫"));

一定要記得用 ActivityMainBinding 類型接收返回的對象,因爲你自動補全的時候生成的類型是 ViewDataBinding 。你不用ActivityMainBinding 接收的話,它是找不到你的bean對應的設置數據方法的。

另外獲取binding還有兩種方法:

第二種方法 

ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);

第二種方法 

View view = getLayoutInflater().inflate(R.layout.activity_main, null);
ActivityMainBinding binding = ActivityMainBinding.bind(view);
setContentView(view);

 

2.  我們來看看佈局 activity_second。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="SecondAvtivityBinding">

        <import type="android.view.View"/>

        <import
            alias="MyView"
            type="com.example.weioule.databindingdemo.View"/>

        <variable
            name="bean"
            type="com.example.weioule.databindingdemo.Bean"/>

    </data>

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginTop="25dp"
            android:text="@{bean.name}"
            android:textSize="15sp"
            android:visibility="@{bean.visible?View.VISIBLE:View.GONE}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginTop="65dp"
            android:text="@{bean.title ?? `title爲空`}"
            android:textSize="15sp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginTop="105dp"
            android:text="@{MyView.txt+`\n\n`+MyView.fun}"
            android:textSize="15sp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="25dp"
            android:layout_marginRight="25dp"
            android:onClick="doNext"
            android:padding="10dp"
            android:text="do next"/>
    </RelativeLayout>
</layout>


我們在上面說過,binding 對象的類名是可以自己定義的,佈局 activity_second 中 data 標籤裏 class = "SecondActivityBinding" 就是我們自己定義的類名 SecondActivityBinding 。

這個類在編譯時被自動生成並放置在module包裏的databinding包下。

另外還有兩種寫法:

<data class=".SecondActivityBinding">
    
<data class="com.example.weioule.databindingdemo.SecondActivityBinding>

這兩種寫法會讓這個類在編譯時被自動生成直接放置在module包下。

import 標籤是導入的意思,可以導入多個,類似我們在類中import,我們上面寫的是導入Android的View組件。導入View組件之後我們在xml裏就可以使用了,第一個TextView的visibility屬性我們就用到了三元運算符,顯示和隱藏直接調用View.VISIBLE和 View.GONE 。

當 import 的類名一樣(有衝突)時,可以把其中一個類重命名,寫法爲: (alias= "xx")

<import type="android.view.View"/>
<import type="com.example.weioule.databindingdemo.View"  alias="MyView"/>

這樣重命名區分之後就可以把 MyView 當 com.example.weioule.databindingdemo裏的View當去使用了:text="@{MyView.txt}"

導入類後就可以在表達式中直接使用static屬性和方法,類名點即可:android:text="@{ MyView.txt +`\n\n`+ MyView.fun }"。

第二個TextView的文本設置我們使用了null合併運算符: "@{bean.title ?? `title爲空`}"

null合併運算符 與三元運算符有些相似,如果第一個操作數不是null 時,整個表達式就等於第一個操作數的值,反之整個表達式就等於第二個操作數的值。

`title爲空` 的反引號是因爲:字符串文本 在屬性值兩邊使用單引號時,則表達式中使用雙引號;也可以使用雙引號來包圍屬性值, 這樣的話,字符串文字則就要使用反引號;

 

3.  我們再來看看 activity_third 佈局。

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <import type="java.util.List"/>

        <variable
            name="list"
            type="List&lt;String>"/>

        <variable
            name="bean"
            type="com.example.weioule.databindingdemo.Bean"/>
    </data>

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

        <include
            android:id="@+id/include"
            layout="@layout/layout_include"
            app:bean="@{bean}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/include"
            android:layout_marginLeft="25dp"
            android:layout_marginTop="10dp"
            android:text="@{bean.name +` `+ @string/str}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="25dp"
            android:layout_marginRight="25dp"
            android:padding="10dp"
            android:text="@{list[0]}"/>
    </RelativeLayout>
</layout>

data元素裏聲明瞭兩個variable數據元素, 一個類型爲String的List集合 list,一個是Bean的實例。

 type="List&lt;String>" 中的【 &lt; 是轉義字符用來替換【 < 】,原文是type="List<String>" 。 否則會報錯編譯不通過

在使用 list 的的時候跟代碼裏一樣,用 [ index ] 就可以了:text="@{ list[0] }"。

arrays、lists、sparse lists以及maps 等集合用法一致。

當 include 另一個佈局的時候,將數據傳過去 app:bean="@{bean}" 。這個 bean 屬性一定要與所 include 的佈局裏 variable 標籤的 name 要一致。否則找不到該屬性就會報錯。

第一個TextView的文本設置 text="@{bean.name +` `+ @string/str}"  是直接引用strings文件裏定義的字符串str,因爲data binding 在xml裏是可以使用正常的表達式來訪問 resources 資源的,包括 dimens 和 colors等。

 

4.  我們看看layout_include。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="bean"
            type="com.example.weioule.databindingdemo.Bean"/>
    </data>

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

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginTop="25dp"
            android:text="@{bean.title??`title爲空`}"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginTop="10dp"
            android:text='@{bean.visible?"visible = true":"visible = flase"}'/>
    </LinearLayout>
</layout>

variable 標籤定義的 name= "bean" ,是可以用屬性的方式給它賦值的,就像上面的 app:bean="@{bean}" 。

第二個TextView的文本設置android:text='@{bean.visible?"visible = true":"visible = flase"}'  是兩邊用的單引號括起來,所以裏面就可以用雙引號來包文字。

 

ok,data binding的基本使用就到這裏了。相信認真看完這篇文章,你也學會data binding的一些基礎使用方法了。

demo項目地址:https://github.com/weioule/DataBindingDemo

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章