Android DataBinding 快速上手

2020-09-20 11:00:54

Data Binding顧名思義就是資料繫結,2015年穀歌I/O大會上釋出了DataBinding,它是一個資料繫結框架,是一種對MVVM的實現,MVVM模式就相當於把 MVC模式中的 C 層換成了VM也就是 ViewModel 層。ViewModel僅僅用來顯示資料的,對於複雜的資料業務邏輯不處理,所以更偏向於View。Data Binding中使用到了ViewModel,它會把ViewModel繫結到 XML檔案中,保證View中的數值來源都是來自ViewModel,降低佈局和邏輯的耦合性,使程式碼邏輯清晰,可以提高開發效率,效能高,功能強大!
開發環境要求
Gradle外掛至少在1.5.0更高,Android studio的版本在1.3.0或更高,可以在Android 2.1(API7+)上使用它。
基本用途:
1.去掉了activity,fragment中的80%的UI程式碼,減少定義View的Id的,不用再去findViewById,自動繫結好Id ,不會因為id錯出現crash。
2.XML變成了UI的唯一真實來源。通過使用Data Binding,XML中的View數值來源都是data標籤中的變數,資料來源比較唯一。
3.保證執行在主執行緒

繫結表示式使用以下運運算元和關鍵字:
1.一元運運算元:+ 、- 、!等
2.二元運運算元: &(與) 、 | (或) 、^(互斥或)
3.移位運運算元:>> 、 >>> 、<<
4.比較運運算元:>= 、 >、 <= 、 < 、== (請注意,< 需要跳脫為 「&lt ;」)
5. instanceof 直接可以看這個範例是不是某個類的繼承
6.分組運運算元 ()
7.在文字上支援character、String、null、numeric
8.cast(型別轉換)
9.方法呼叫 (可以用「.」點號,也可以用兩個"::「冒號來調方法名)
10.Field存取(get函數…)
11.Array存取,直接在 xml中存取陣列,指定下標存取陣列中元素,但是要注意陣列越界的問題
12.三元運運算元?:
13空合併運運算元 (例子 android:text=」@{user.displayName ?? user.lastName}「完全等價於android:text=」@{user.displayName != null ? user.displayName : user.lastName}")
14.自動空指標檢查 (例子 {user.displayName} ->null 如果user類為空,那麼自動賦值為null。{user.age} ->0如果user類為空,那麼自動賦值為0。)
15.Margin @dimen+@dimen (例子 android:layout_margin="@{@activity_horizontal_margin+@activity_verticall_margin}" )

表示式語法不支援以下操作:
1.this 不能在xml中存取this關鍵字
2.super 不能在xml中呼叫父類別的方法
3.new 不能在xml中new出實列
4.不支援顯示泛型呼叫

Include標籤
1.在使用了 app 名稱空間的佈局中,可以將變數傳遞到include佈局的繫結中,以下範例顯示了將user變數傳遞到name.xml和contact.xml佈局檔案中(前提是name.xml和contact.xml佈局中宣告了user變數):

在這裡插入圖片描述

2.資料繫結不支援 include直接作為merge的子元素,根佈局必須是ViewGroup,換句話說,外層必須要有LinearLayout、RelativeLayout等像這樣的容器裹著,才不會出現生成的某些view被覆蓋的問題出現。例如,不支援以下佈局:

在這裡插入圖片描述

Observable是個介面,Google為我們提供了一個BaseObservable類,我們只要把Model類繼承自它,就獲得了通知UI更新資料的能力了,然後再getter方法上新增Bindable註解,在setter方法中使用notifying提醒UI更新資料。如:
在這裡插入圖片描述

Google也推出ObservableFields類,使用它我們可以簡化我們的Model類,如:
在這裡插入圖片描述
那一堆程式碼就變成了兩行,然後通過:
在這裡插入圖片描述
設定和獲取資料,更新UI。當然ObservableField中傳入的泛型可以是java中的基本型別,當然我們還可以使用 ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, ObservableParcelable等具體的型別,效果也和ObservableField是一樣的,如:
在這裡插入圖片描述
而且Google也為我們提供了一些通知型別的集合,有這三種:ObservableArrayList、ObservableArrayMap<K,V>、ObservableMap<K,V>,它和平場使用的List、Map用法一樣,但是多了通知功能。
我們在layout中的區域匯入包後就可以直接用它了,當它內部的資料發生改變時就自動會通知UI介面更新。如:在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
高階繫結,動態變數
1.立即繫結。變數或Observable改變後,會在下個幀進行繫結的改變,如果需要立即執行,可以執行executePendingBindings() 方法。
2.後臺執行緒。data binding會在地化變數/值域,以避免同步問題(但對collection不行)。
動態變數多用於RecyclerView,有時候item佈局樣式不是單一的,存在多種佈局,那麼就會存在多種ViewHolder 型別。在發生資料繫結的時候,我們並不知道繫結的是哪個layout,ViewHolder的範例是哪一個,這時候就可以在onBindViewHolder函數裡面加入以下類似程式碼:

//根據位置拿到item的資料
final T item=mltems.get(position);

//在所有的item的Variable裡面都定義同樣的名字叫「item」,這樣就可以綁 定到對應的layout了
holder.getBinbgding().setVariable(BR.item,item);

//因為RecyclerView的view是重用的,所以要立即重新整理
holder.getBinding().exectePendingBindings();

Bingding生成
1.預設生成規則,下劃線分割,大寫開頭 如activity_main.xml ->ActivityMainBinding
2.自定義class, <data class ="LionActive> …生成的Bingding就是LionActive

最後附上官方的使用教學:https://blog.gokit.info