觀測能力是指物件在資料變更時通知其他人的功能。資料繫結程式庫可讓您將物件、欄位或集合設為可觀察。
您可以使用任何物件進行資料繫結,但修改物件不會自動導致 UI 更新。您可以使用資料繫結,讓資料物件在資料變更時通知其他物件 (稱為事件監聽器)。可觀察類別分為三種:欄位、集合和物件。
當這些可觀測資料物件繫結至 UI,且資料物件的屬性有所變更時,UI 會自動更新。
可觀察欄位
如果您的類別只有少數屬性,則建立實作 Observable
介面的類別可能並不值得。在此情況下,您可以使用一般 Observable
類別和下列原始類別,讓欄位變成可觀察狀態:
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
可觀察欄位是獨立的可觀察物件,其中包含單一欄位。原始版本可避免在存取作業期間進行拳擊和開箱。如要使用這項機制,請以 Java 程式設計語言建立 public final
屬性,或在 Kotlin 中建立唯讀屬性,如以下範例所示:
Kotlin
class User { val firstName = ObservableField<String>() val lastName = ObservableField<String>() val age = ObservableInt() }
Java
private static class User { public final ObservableField<String> firstName = new ObservableField<>(); public final ObservableField<String> lastName = new ObservableField<>(); public final ObservableInt age = new ObservableInt(); }
如要存取欄位值,請使用 set()
和 get()
存取子方法,或使用 Kotlin 屬性語法:
Kotlin
user.firstName = "Google" val age = user.age
Java
user.firstName.set("Google"); int age = user.age.get();
可觀察的集合
部分應用程式會使用動態結構保留資料。可觀測的集合可讓您使用索引鍵存取這些結構。當鍵是參照類型 (例如 String
) 時,ObservableArrayMap
類別非常實用,如以下範例所示:
Kotlin
ObservableArrayMap<String, Any>().apply { put("firstName", "Google") put("lastName", "Inc.") put("age", 17) }
Java
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("firstName", "Google"); user.put("lastName", "Inc."); user.put("age", 17);
在版面配置中,您可以使用字串鍵尋找地圖,如以下範例所示:
<data>
<import type="android.databinding.ObservableMap"/>
<variable name="user" type="ObservableMap<String, Object>"/>
</data>
…
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="@{String.valueOf(1 + (Integer)user.age)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
當索引鍵是整數時,ObservableArrayList
類別非常實用,如下所示:
Kotlin
ObservableArrayList<Any>().apply { add("Google") add("Inc.") add(17) }
Java
ObservableArrayList<Object> user = new ObservableArrayList<>(); user.add("Google"); user.add("Inc."); user.add(17);
在版面配置中,您可以透過索引存取清單,如以下範例所示:
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
android:text='@{user[Fields.LAST_NAME]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
可觀察的物件
藉由實作 Observable
介面的類別,您可以註冊監聽器,接收可觀測物件的屬性變更通知。
Observable
介面提供新增和移除事件監聽器的機制,但您可以決定通知的傳送時間。為簡化開發作業,資料繫結程式庫提供 BaseObservable
類別,其會實作事件監聽器註冊機制。實作 BaseObservable
的資料類別負責在屬性變更時收到通知。方法是將 Bindable
註解指派給 getter,然後在 setter 中呼叫 notifyPropertyChanged()
方法,如以下範例所示:
Kotlin
class User : BaseObservable() { @get:Bindable var firstName: String = "" set(value) { field = value notifyPropertyChanged(BR.firstName) } @get:Bindable var lastName: String = "" set(value) { field = value notifyPropertyChanged(BR.lastName) } }
Java
private static class User extends BaseObservable { private String firstName; private String lastName; @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } }
資料繫結會在模組套件中產生名為 BR
的類別,其中包含用於資料繫結的資源 ID。Bindable
註解會在編譯期間產生 BR
類別檔案中的項目。如果資料類別的基礎類別無法變更,您可以使用 PropertyChangeRegistry
物件實作 Observable
介面,有效率地註冊及通知事件監聽器。
生命週期感知物件
應用程式中的版面配置也可以繫結至資料繫結來源,自動向 UI 通知資料異動。如此一來,繫結具有生命週期感知特性,且只會於 UI 在畫面上顯示時觸發。
資料繫結支援 StateFlow
和 LiveData
。如要進一步瞭解如何在資料繫結中使用 LiveData
,請參閱「使用 LiveData 通知 UI 有關資料變更的資訊」。
使用 StateFlow
如果應用程式將 Kotlin 與協同程式搭配使用,您可以使用 StateFlow
物件做為資料繫結來源。如要將 StateFlow
物件與繫結類別搭配使用,請指定生命週期擁有者來定義 StateFlow
物件的範圍。以下範例指定在繫結類別執行個體化後,將活動指定為生命週期擁有者:
class ViewModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Inflate view and obtain an instance of the binding class.
val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)
// Specify the current activity as the lifecycle owner.
binding.lifecycleOwner = this
}
}
如「架構元件的繫結版面配置檢視畫面」所述,資料繫結可與 ViewModel
物件完美搭配運作。您可以同時使用 StateFlow
和 ViewModel
,如下所示:
class ScheduleViewModel : ViewModel() {
private val _username = MutableStateFlow<String>("")
val username: StateFlow<String> = _username
init {
viewModelScope.launch {
_username.value = Repository.loadUserName()
}
}
}
在版面配置中,使用繫結運算式將 ViewModel
物件的屬性和方法指派給對應的檢視畫面,如以下範例所示:
<TextView
android:id="@+id/name"
android:text="@{viewmodel.username}" />
每當使用者名稱值變更時,使用者介面就會自動更新。
停用 StateFlow 支援
如果應用程式使用 Kotlin 和 AndroidX,資料繫結會自動納入 StateFlow
支援功能。這表示如果協同程式尚未取得依附元件,會自動在應用程式中加入協同程式依附元件。
如要停用這項功能,請在 build.gradle
檔案中加入以下內容:
Groovy
android { ... dataBinding { addKtx = false } }
Kotlin
android { ... dataBinding { addKtx = false } }
您也可以在 gradle.properties
檔案中加入以下這行程式碼,在專案中全域停用 StateFlow
:
Groovy
android.defaults.databinding.addKtx = false
Kotlin
android.defaults.databinding.addKtx = false
其他資源
如要進一步瞭解資料繫結,請參閱下列其他資源:
範例
程式碼研究室
網誌文章
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- ViewModel 的已儲存狀態模組
- 將版面配置視圖與架構元件繫結
- Paging 程式庫總覽