MVVM&Android實踐(一):DataBinding入門


瞭解DataBinding的使用,請參考:

官網

如果你暫時無法翻牆,看這篇文章也可以。

本文中,默認的View就是Activity及其對應的XML文件。

第一部分:DataBinding入門

配置項

在Android中,需要使用DataBinding來支持MVVM的雙向綁定。

在Android中的DataBinding需要在module下的build.gradle中申明:

android {
	// ......
    dataBinding{
        enabled = true
    }
    // ......
}

Layout標籤使用

想讓DataBinding生效,還需要在View對應的XML中間中使用layout標籤,它就像個命名空間一樣。類似於:

<?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"
    xmlns:tools="http://schemas.android.com/tools">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

在這個layout標籤包裹的命名空間下,有一個data標籤,你可以通過該標籤,在View的XML文件中引入Model的變量,這個留在後面說。

我們前面說了在MVVM中,Activity和對應的XML文件共同組成了View,那麼它們是怎麼聯繫到一起得呢?

一般來說,XML文件,通過Activity的setContentView函數,將XML文件,交給Activity控制。就像這樣:

setContentView(R.layout.activity_main);

那麼,在DataBinding框架下,我們得換個新得姿勢:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // setContentView(R.layout.activity_main);
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
}

setContentView的函數名相同,但調用實例卻從傳統的Activity換成了DataBindingUtil的靜態函數。

聰明的小夥伴已經注意到了,爲啥莫名其妙多了個ActivityMainBinding類?這不是我乾的!!!!解釋一下。

當你在XML文件中正確的添加了<layout></layout>標籤時,AndroidStudio會通過DataBinding框架,自動生成了一個類,這個類的包名遵循如下規則:

規則一:項目包名.databinding.XML文件去掉下劃線首字母大寫+Binding

例如,我的XML文件名稱爲activity_main.xml,通過DataBinding框架生成的包類名爲:

com.dali.mvvmdemo.databinding.ActivityMainBinding;

其實,從這種簡單的命名規則中也可以看出,通過DataBindingUtil.setContentView將哪個xml文件綁定到activity,函數的返回值就是遵循了規則一的類實例。

那麼binding類的命名就只能使用DataBinding框架生成的麼?當然不是,DataBinding的<data>標籤中,可以定義當前xml生成binding類的類名。像這樣:

<data class="CustomBinding">
    <variable
              name="person"
              type="com.superli.mvvmdemo.User" />
</data>

class的值就是自定義binding類的類名,它的固定類全名爲:com.superli.mvvmdemo.databinding.CustomBinding; 這意味着,在所有使用到該類的地方,你需要添加的導入語句是:

import com.superli.mvvmdemo.databinding.CustomBinding;

比如在Activity中。

通過這個實例,我們可以直接操作xml文件中所有帶idview,而再也不用findViewById了。

上述就是最簡單的DataBinding的使用了,經過了這兩步,你運行起來的APP,就可以說使用了DataBinding框架。我們來小結一下,基本步驟:

  1. 在Activity對應的XML文件中,在最外層包裹<layout></layout>標籤,使DataBinding框架生成對應的binding類。
  2. 在activity中,通過DataBindingUtil.setContentView,將Xml以Binding實例的方式,提供給activity操作。

數據綁定

我們已經知道,在通過DataBindingUtil.setContentView函數,獲取了xml對應的binding實例之後,可以通過該實例操作xml文件。那麼具體怎麼做呢?

還是先從xml文件說起,前面提到,DataBinding的<layout></layout>類似於一個命名空間,在該空間下,包含了一個<data></data>標籤和<variable/>標籤。看一下示例:

<?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"
    xmlns:tools="http://schemas.android.com/tools">
    
    <data>
        <variable
            name="person"
            type="com.dali.mvvmdemo.User" />
    </data>
	<!-- 其它佈局代碼 -->
</layout>

這裏有兩個陌生的標籤:<data><variable>

  • <data>標籤:表示標籤內的代碼都將作爲xml的binding類的一部分。
  • <variable>標籤:該標籤中,申明瞭一個變量,和它對應的類。type表示類,name表示變量名,編譯時,DataBinding將會把改變量申明到xml對應的binding類中。

那麼,這段代碼有啥用呢?

xml文件有了這段申明後,就可以在xml文件中自由的使用com.dali.mvvmdemo.User類型的所有成員變量或者函數了,當然,還是得通過類的實例變量person

第一種綁定方法

一種比較典型的用法如下:

<TextView
          android:id="@+id/tv_age"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text='@{String.valueOf(person.mAge), default="Default"}'
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintLeft_toLeftOf="parent"
          app:layout_constraintRight_toRightOf="parent"
          app:layout_constraintTop_toBottomOf="@id/tv_name"/>

使用“@{}”將需要使用的變量包裹起來,中間就可以像寫Java代碼一樣使用了。因爲這裏的person.mAge是int類型,所以使用String.valueOf將數值類型轉換成了字符串類型。

default="Default":表示,在佈局文件預覽時顯示的值。

通常xml生成的binding類中,直接引用了java.lang包下的類,所以我們這裏可以直接使用String類型,當基本類型無法滿足你時,你可以通過<import type="com.dali.mvvmdemo.User"/>導入你需要的類型,當然,這部分暫時不開展。

User此時就是個簡單的JavaBean類:

public class User {
    public String mName;
    public int mAge;

    public User(String name, int age){
        mName = name;
        mAge = age;
    }
}

綁定是綁定了,那麼數據從哪兒來呢?看完下一個代碼片段,你就明白了:

public class MainActivity extends AppCompatActivity {
    private User user = new User("SuperLi", 3);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setPerson(user); // 將xml中的person變量和當前對象中的user變量綁定起來。
    }
}

當xml的variable標籤中,申明瞭變量名稱後,DataBinding會在生成的xml binding類中,生成對應的setXXX函數,以便將類實例的引用賦值給binding類中對應的變量XXX

例如:我的activity_main.xml的binding類是:ActivityMainBindingImpl,在activity_main.xml中有person變量申明如下:

<variable
    name="person"
    type="com.dali.mvvmdemo.User" />

那麼,ActivityMainBindingImpl類中,將會生成如下代碼:

public class ActivityMainBindingImpl extends ActivityMainBinding  {
	// ...
	public void setPerson(@Nullable com.dali.mvvmdemo.User Person) {
        this.mPerson = Person;
        // ...
    }
    // ...
}

這是最常用最經典的綁定方式。

第二種常規方式

另外一種就是ViewId直接設置數據。還是以之前的xml代碼爲例:

<TextView
          android:id="@+id/tv_age"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{String.valueOf(person.mAge)}"
          app:layout_constraintBottom_toBottomOf="parent"
          app:layout_constraintLeft_toLeftOf="parent"
          app:layout_constraintRight_toRightOf="parent"
          app:layout_constraintTop_toBottomOf="@id/tv_name"/>

TextView的id爲tv_age,xml的binding類生成時,會有一個tvAge的成員變量,通過它,可以操作當前TextView,比如:

binding.tvAge.setText("1000");

和binding類名生成的規則類似,以下劃線分割,第二個名字開始首字母大寫。只不過TextView的id作爲變量名稱首字母小寫,binding類作爲類名首字母大寫而已。

發佈了79 篇原創文章 · 獲贊 30 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章