Android Jetpack——DataBinding
寫在前面
谷歌推出Android Jetpack已經很久了,還有AndroidX,但是呢,包括MVVM都還不怎么去用,所以有必要亡羊補牢一下了,接下來是對Android Jetpack系列進行學習,網上的資料有點雜,所以決定直接看谷歌開發(fā)者文檔:Android Developers,順便記錄一下,所以沒有介紹等等話題,DataBinding主要是可以去掉繁瑣的findViewByID,可以讓界面跟布局雙向綁定數據,并且互相更新數據,直接碼代碼。
1、依賴
在項目的build.gradle添加配置


2、xml布局文件
與我們以往不同的是,現在布局的標簽必須是以layout開頭
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
? ? <data>
? ? ? ? <variable
? ? ? ? ? ? name="user"
? ? ? ? ? ? type="com.tenz.tenzdatabinding.User" />
? ? ? ? <variable
? ? ? ? ? ? name="onClickListener"
? ? ? ? ? ? type="com.tenz.tenzdatabinding.MainActivity.OnClickListener" />
? ? </data>
? ? <LinearLayout
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="match_parent"
? ? ? ? android:orientation="vertical">
? ? ? ? <TextView
? ? ? ? ? ? android:id="@+id/tv_name"
? ? ? ? ? ? android:layout_width="match_parent"
? ? ? ? ? ? android:layout_height="50dp"
? ? ? ? ? ? android:layout_marginTop="10dp"
? ? ? ? ? ? android:gravity="center"
? ? ? ? ? ? android:text="@{user.name,default=name}"
? ? ? ? ? ? android:textColor="#000000"
? ? ? ? ? ? android:textSize="16sp"/>
? ? ? ? <TextView
? ? ? ? ? ? android:id="@+id/tv_age"
? ? ? ? ? ? android:layout_width="match_parent"
? ? ? ? ? ? android:layout_height="50dp"
? ? ? ? ? ? android:layout_marginTop="10dp"
? ? ? ? ? ? android:gravity="center"
? ? ? ? ? ? android:text="@{String.valueOf(user.age),default=age}"
? ? ? ? ? ? android:textColor="#000000"
? ? ? ? ? ? android:textSize="16sp"/>
? ? ? ? <Button
? ? ? ? ? ? android:layout_width="match_parent"
? ? ? ? ? ? android:layout_height="wrap_content"
? ? ? ? ? ? android:layout_marginTop="10dp"
? ? ? ? ? ? android:text="增加年齡"
? ? ? ? ? ? android:textSize="16sp"
? ? ? ? ? ? android:textColor="#000000"
? ? ? ? ? ? android:onClick="@{() -> onClickListener.addAge()}"/>
? ? </LinearLayout>
</layout>
其中,layout 標簽是根標簽,data標簽就是你要在布局里面引用的對象,例如這里引用了User的實體類,@{user.name,default=name}就是TextView綁定了user的name字段,默認是“name”,如果你需要設置int類型的,需要轉換一下@{String.valueof(user.age),default=age}。
3、activity或fragment
activity或fragment當然也有變化
package com.tenz.tenzdatabinding;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import com.tenz.tenzdatabinding.databinding.ActivityMainBinding;
public class MainActivityextends AppCompatActivity {
private ActivityMainBindingdataBinding;
? ? private UsermUser;
? ? public class OnClickListener{
public void addAge(){
mUser.setAge(mUser.getAge()+1);
? ? ? ? }
}
@Override
? ? protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
? ? ? ? dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
? ? ? ? mUser =new User();
? ? ? ? mUser.setName("Tenz");
? ? ? ? mUser.setAge(18);
? ? ? ? dataBinding.setUser(mUser);
? ? ? ? dataBinding.setOnClickListener(new OnClickListener());
? ? }
}
在這里我們用到了DataBindingUtil來綁定xml布局,ActivityMainBinding是編譯之后自動生成,還有我們需要對xml聲明的data標簽進行綁定,例如User。
4、數據的雙向綁定更新
我們上面的xml有姓名跟年齡兩個TextView,分別綁定了user的name跟age,然后我們在activity對User進行了數據初始化并進行了對xml的user的綁定,運行之后會看到已經在TextView有數據顯示了。但是我現在想點擊一個按鈕,讓年齡進行自增呢?我們先跳過事件處理這一步,我在按鈕的點擊事件對綁定的User的年齡進行了自增,但是卻發(fā)現沒有效果,因為我們的實體類User需要做一些處理,
package com.tenz.tenzdatabinding;
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
public class User extends BaseObservable {
private Stringname;
? ? private Stringavator;
? ? private Stringsex;
? ? private int age;
? ? @Bindable
? ? public StringgetName() {
return name;
? ? }
public void setName(String name) {
this.name = name;
? ? }
@Bindable
? ? public StringgetAvator() {
return avator;
? ? }
public void setAvator(String avator) {
this.avator = avator;
? ? }
@Bindable
? ? public StringgetSex() {
return sex;
? ? }
public void setSex(String sex) {
this.sex = sex;
? ? }
@Bindable
? ? public int getAge() {
return age;
? ? }
public void setAge(int age) {
this.age = age;
? ? ? ? notifyPropertyChanged(com.tenz.tenzdatabinding.BR.age);
? ? }
}
首先是我們的實體類需要繼承BaseObservable ,然后在get方法添加@Bindable注解,還有在我們的set方法調用一個notifyPropertyChanged方法,我們再次點擊按鈕就會發(fā)現年齡會有變化了。
5、事件處理
我們以前是用點擊事件是findViewById().setOnClikckListener(),現在有點不一樣,上面我在activity聲明了一個OnClickListener類,OnClickListener類里面聲明了addAge方法,而且我在xml布局已經進行了聲明,然后在Button的添加點擊處理
<Button
? ? android:layout_width="match_parent"
? ? android:layout_height="wrap_content"
? ? android:layout_marginTop="10dp"
? ? android:text="增加年齡"
? ? android:textSize="16sp"
? ? android:textColor="#000000"
? ? android:onClick="@{() -> onClickListener.addAge()}"/>
無參:@{() -> onClickListener.addAge()}
有參:@{(view) -> onClickListener.addAge(view)} 或 @{(view) -> onClickListener.addAge(view)}
或?@{() -> onClickListener.addAge(user)}
附上demo,demo也做了RecycleView使用DataBinding綁定數據,實現了點擊item使數據更改,github地址:TenzMixMaster/tenzdatabinding at master · TenzLiu/TenzMixMaster · GitHub