產生的繫結類別

資料繫結程式庫會產生繫結類別,可用於存取版面配置的變數和檢視畫面。本說明文件說明如何建立及自訂產生的繫結類別。

產生的繫結類別會將版面配置變數連結至版面配置中的檢視畫面。您可以自訂繫結的名稱和套件。所有產生的繫結類別都會繼承自 ViewDataBinding 類別。

系統會為每個版面配置檔案產生繫結類別。根據預設,類別的名稱會是轉換為 Pascal 大小寫的版面配置檔案名稱,並在其中加入 Binding 後置字串。舉例來說,如果版面配置檔案名稱為 activity_main.xml,則對應的產生類別為 ActivityMainBinding。這個類別會保留版面配置屬性中的所有繫結至版面配置的檢視畫面,且知道如何指派繫結運算式的值。

建立繫結物件

在加載版面配置後立即建立繫結物件,以確保檢視區塊階層在繫結至版面配置中具有運算式的檢視區塊前不會遭到修改。將物件繫結至版面配置最常見的方法,是在繫結類別上使用靜態方法。您可以使用繫結類別的 inflate() 方法加載檢視區塊階層,並將物件繫結至該階層,如以下範例所示:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater)

    setContentView(binding.root)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater());

    setContentView(binding.root);
}

inflate() 方法的替代版本除了使用 LayoutInflater 物件之外,也採用 ViewGroup 物件,如以下範例所示:

Kotlin

val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)

Java

MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);

如果以其他機制加載版面配置,您可以分別繫結,如下所示:

Kotlin

val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)

Java

MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);

有時候,您不知道繫結類型。在這種情況下,您可以使用 DataBindingUtil 類別建立繫結,如以下程式碼片段所示:

Kotlin

val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent)
val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)

Java

View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bind(viewRoot);

如要在 FragmentListViewRecyclerView 轉接程式中使用資料繫結項目,建議使用繫結類別的 inflate() 方法或 DataBindingUtil 類別,如以下程式碼範例所示:

Kotlin

val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
// or
val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

Java

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

含有 ID 的檢視表

資料繫結程式庫會為每個在版面配置中具有 ID 的檢視畫面,在繫結類別中建立不可變更的欄位。舉例來說,資料繫結程式庫會透過以下版面配置建立 TextView 類型的 firstNamelastName 欄位:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"
   android:id="@+id/firstName"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"
  android:id="@+id/lastName"/>
   </LinearLayout>
</layout>

程式庫會在單次傳遞中,從檢視區塊階層擷取檢視畫面 (包括 ID)。這個機制會比針對版面配置中的每個檢視畫面呼叫 findViewById() 方法更快。

由於 ID 沒有資料繫結,因此不需要用到這類 ID,但在某些情況下,仍須透過程式碼存取檢視畫面。

Variables

資料繫結程式庫會針對版面配置中宣告的每個變數產生存取子方法。舉例來說,下列版面配置會在 userimagenote 變數的繫結類別中產生 setter 和 getter 方法:

<data>
   <import type="android.graphics.drawable.Drawable"/>
   <variable name="user" type="com.example.User"/>
   <variable name="image" type="Drawable"/>
   <variable name="note" type="String"/>
</data>

查看虛設常式

與一般檢視畫面不同,ViewStub 物件會以隱形檢視畫面開始形式啟動,當這些圖片顯示或明確加載時,它們會加載其他版面配置,在版面配置中取代其本身。

由於 ViewStub 會從檢視區塊階層消失,因此繫結物件中的檢視區塊也必須消失,才能利用垃圾收集程序聲明該檢視區塊。由於檢視畫面為最終版本,因此 ViewStubProxy 物件會取代產生的繫結類別中 ViewStub,讓您存取 ViewStub 時是否存在,以及在 ViewStub 加載時存取加載的檢視區塊階層。

加載其他版面配置時,必須為新的版面配置建立繫結。因此,ViewStubProxy 必須監聽 ViewStub OnInflateListener,並視需要建立繫結。由於一次只能存在一個事件監聽器,因此 ViewStubProxy 可讓您設定 OnInflateListener,並在建立繫結後呼叫。

立即繫結

當變數或可觀察的物件變更時,繫結會在下一個影格之前變更。但在某些情況下,繫結必須立即執行。如要強制執行,請使用 executePendingBindings() 方法。

動態變數

有時候,特定繫結類別不明。舉例來說,針對任意版面配置執行的 RecyclerView.Adapter 無法得知特定的繫結類別。它必須在呼叫 onBindViewHolder() 方法時指派繫結值。

在以下範例中,RecyclerView 繫結至包含 item 變數的所有版面配置。BindingHolder 物件的 getBinding() 方法會傳回 ViewDataBinding 基礎類別。

Kotlin

override fun onBindViewHolder(holder: BindingHolder, position: Int) {
    item: T = items.get(position)
    holder.binding.setVariable(BR.item, item);
    holder.binding.executePendingBindings();
}

Java

public void onBindViewHolder(BindingHolder holder, int position) {
    final T item = items.get(position);
    holder.getBinding().setVariable(BR.item, item);
    holder.getBinding().executePendingBindings();
}

背景執行緒

只要資料模型不是集合,您就可以在背景執行緒中變更資料模型。評估期間,資料繫結會將每個變數或欄位本地化,以免發生並行問題。

自訂繫結類別名稱

根據預設,繫結類別是根據版面配置檔案名稱所產生,開頭是大寫字母、移除底線 ( _ )、將下列字母大寫,並在字詞 Binding 後加上字。舉例來說,版面配置檔案 contact_item.xml 會產生 ContactItemBinding 類別。該類別會放在模組套件下的 databinding 套件中。舉例來說,如果模組套件是 com.example.my.app,繫結類別就會放入 com.example.my.app.databinding 套件中。

調整 data 元素的 class 屬性可重新命名繫結類別,或將其放在不同的套件中。舉例來說,下列版面配置會在目前模組的 databinding 套件中產生 ContactItem 繫結類別:

<data class="ContactItem">
    ...
</data>

您可以在其他套件中產生繫結類別,方法是在類別名稱前面加上半形句號。以下範例會在模組套件中產生繫結類別:

<data class=".ContactItem">
    ...
</data>

您也可以使用要產生繫結類別的完整套件名稱。以下範例會在 com.example 套件中建立 ContactItem 繫結類別:

<data class="com.example.ContactItem">
    ...
</data>

其他資源

如要進一步瞭解資料繫結,請參閱下列其他資源。