使用單向資料繫結,您可以在屬性上設定值,並設定對該屬性變更做出反應的事件監聽器:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@{viewmodel.rememberMe}" android:onCheckedChanged="@{viewmodel.rememberMeChanged}" />
雙向資料繫結提供這項程序的捷徑:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@={viewmodel.rememberMe}" />
@={} 標記法 (其中包含「=」符號) 會接收屬性的資料變更,並同時監聽使用者更新。
如要回應備份資料的變更,您可以將版面配置變數設為 Observable 的實作項目 (通常是 BaseObservable),並使用 @Bindable 註解,如以下程式碼片段所示:
Kotlin
class LoginViewModel : BaseObservable {
// val data = ...
@Bindable
fun getRememberMe(): Boolean {
return data.rememberMe
}
fun setRememberMe(value: Boolean) {
// Avoids infinite loops.
if (data.rememberMe != value) {
data.rememberMe = value
// React to the change.
saveData()
// Notify observers of a new value.
notifyPropertyChanged(BR.remember_me)
}
}
}
Java
public class LoginViewModel extends BaseObservable {
// private Model data = ...
@Bindable
public Boolean getRememberMe() {
return data.rememberMe;
}
public void setRememberMe(Boolean value) {
// Avoids infinite loops.
if (data.rememberMe != value) {
data.rememberMe = value;
// React to the change.
saveData();
// Notify observers of a new value.
notifyPropertyChanged(BR.remember_me);
}
}
}
由於可繫結屬性的 getter 方法稱為 getRememberMe(),因此屬性對應的 setter 方法會自動使用 setRememberMe() 名稱。
如要進一步瞭解如何使用 BaseObservable 和 @Bindable,請參閱「使用可觀測的資料物件」。
使用自訂屬性進行雙向資料繫結
平台提供最常見的雙向屬性和變更事件監聽器的雙向資料繫結實作,您可以在應用程式中使用。如要搭配自訂屬性使用雙向資料繫結,您需要使用 @InverseBindingAdapter 和 @InverseBindingMethod 註解。
舉例來說,如要在名為 MyView 的自訂檢視畫面中,為 "time" 屬性啟用雙向資料繫結,請完成下列步驟:
使用
@BindingAdapter註解設定初始值的方法,並在值變更時更新:Kotlin
@BindingAdapter("time") @JvmStatic fun setTime(view: MyView, newValue: Time) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue } }Java
@BindingAdapter("time") public static void setTime(MyView view, Time newValue) { // Important to break potential infinite loops. if (view.time != newValue) { view.time = newValue; } }使用
@InverseBindingAdapter為從檢視畫面讀取值的方法加上註解:Kotlin
@InverseBindingAdapter("time") @JvmStatic fun getTime(view: MyView) : Time { return view.getTime() }Java
@InverseBindingAdapter("time") public static Time getTime(MyView view) { return view.getTime(); }
此時,資料繫結知道資料變更時該怎麼做 (呼叫加上 @BindingAdapter 註解的方法),以及檢視區塊屬性變更時該呼叫什麼 (呼叫 InverseBindingListener)。不過,資料繫結不知道屬性何時變更或如何變更。
因此,您必須在檢視畫面上設定事件監聽器。這可以是與自訂檢視區塊相關聯的自訂事件監聽器,也可以是一般事件,例如失去焦點或文字變更。將 @BindingAdapter 註解新增至設定屬性變更監聽器的方法:
Kotlin
@BindingAdapter("app:timeAttrChanged")
@JvmStatic fun setListeners(
view: MyView,
attrChange: InverseBindingListener
) {
// Set a listener for click, focus, touch, etc.
}
Java
@BindingAdapter("app:timeAttrChanged")
public static void setListeners(
MyView view, final InverseBindingListener attrChange) {
// Set a listener for click, focus, touch, etc.
}
事件監聽器包含 InverseBindingListener 做為參數。您可以使用 InverseBindingListener,告知資料繫結系統屬性已變更。接著,系統就可以開始呼叫使用 @InverseBindingAdapter 註解的方法。
在實際操作中,這個事件監聽器包含一些非一般邏輯,包括單向資料繫結的事件監聽器。如需範例,請參閱文字屬性變更的轉接器 TextViewBindingAdapter。
轉換人數
如果繫結至 View 物件的變數在顯示前需要設定格式、翻譯或變更,可以使用 Converter 物件。
舉例來說,假設有一個顯示日期的 EditText 物件:
<EditText
android:id="@+id/birth_date"
android:text="@={Converter.dateToString(viewmodel.birthDate)}"
/>
viewmodel.birthDate 屬性包含 Long 類型的值,因此需要使用轉換器設定格式。
由於使用的是雙向運算式,因此也需要反向轉換器,讓程式庫知道如何將使用者提供的字串轉換回備份資料類型,在本例中為 Long。如要這樣做,請將 @InverseMethod 註解新增至其中一個轉換器,並讓這個註解參照反向轉換器。這項設定的範例如以下程式碼片段所示:
Kotlin
object Converter {
@InverseMethod("stringToDate")
@JvmStatic fun dateToString(
view: EditText, oldValue: Long,
value: Long
): String {
// Converts long to String.
}
@JvmStatic fun stringToDate(
view: EditText, oldValue: String,
value: String
): Long {
// Converts String to long.
}
}
Java
public class Converter {
@InverseMethod("stringToDate")
public static String dateToString(EditText view, long oldValue,
long value) {
// Converts long to String.
}
public static long stringToDate(EditText view, String oldValue,
String value) {
// Converts String to long.
}
}
使用雙向資料繫結的無限迴圈
使用雙向資料繫結時,請小心不要引入無限迴圈。當使用者變更屬性時,系統會呼叫使用 @InverseBindingAdapter 註解的方法,並將值指派給備份屬性。這會呼叫使用 @BindingAdapter 註解的方法,進而觸發對使用 @InverseBindingAdapter 註解的方法的另一個呼叫,並繼續迴圈。
因此,請務必在以 @BindingAdapter 註解的方法中比較新舊值,以中斷可能發生的無限迴圈。
雙向屬性
當您使用下表中的屬性時,平台會提供雙向資料繫結的內建支援。如要進一步瞭解平台如何提供這項支援,請參閱對應繫結轉接器的實作方式:
| 類別 | 屬性 | 繫結轉接器 |
|---|---|---|
AdapterView
|
android:selectedItemPositionandroid:selection |
AdapterViewBindingAdapter
|
CalendarView |
android:date |
CalendarViewBindingAdapter
|
CompoundButton |
android:checked
|
CompoundButtonBindingAdapter
|
DatePicker
|
android:yearandroid:monthandroid:day |
DatePickerBindingAdapter
|
NumberPicker |
android:value
|
NumberPickerBindingAdapter
|
RadioButton
|
android:checkedButton |
RadioGroupBindingAdapter
|
RatingBar
|
android:rating
|
RatingBarBindingAdapter
|
SeekBar
|
android:progress |
SeekBarBindingAdapter
|
TabHost
|
android:currentTab |
TabHostBindingAdapter
|
TextView
|
android:text
|
TextViewBindingAdapter
|
TimePicker
|
android:hourandroid:minute |
TimePickerBindingAdapter
|
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 使用可觀察的資料物件
- 版面配置與繫結的運算式
- 將版面配置檢視畫面與架構元件建立繫結