使用单向数据绑定,您可以在属性上设置值, 对该属性的变化做出响应的监听器:
<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
注释。
例如,如果要对 "time"
属性启用双向数据绑定 在名为 MyView
的自定义视图中,完成以下步骤:
为用于设置初始值并在值更新时更新的方法添加注解 使用
@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
类型的值,因此需要 转换数据。
由于使用了双向表达式,因此还需要使用反向表达式 conversioner,用于告知库如何将用户提供的字符串转换回 后备数据类型,在本例中为 Long
。这个过程是通过将 @InverseMethod
注解 传递给其中一个转换器,并让这个注解引用反向的 转换器。以下代码中显示了此配置的示例 snippet:
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
注解的方法中的新值和旧值。
双向特性
当您使用 API 时,该平台内置了对双向数据绑定的支持。 下表中的属性。如需详细了解该平台如何提供 请参阅相应绑定适配器的实现:
类 | 特性 | 绑定适配器 |
---|---|---|
AdapterView | android:selectedItemPosition android:selection | AdapterViewBindingAdapter |
CalendarView | android:date | CalendarViewBindingAdapter |
CompoundButton | android:checked | CompoundButtonBindingAdapter |
DatePicker | android:year android:month android: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:hour android:minute | TimePickerBindingAdapter |
其他资源
如需详细了解数据绑定,请参阅以下资源: 其他资源
示例
Codelab
- <ph type="x-smartling-placeholder"></ph> Android 数据绑定 Codelab
博文
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- 使用可观察的数据对象
- 布局和绑定表达式
- 将布局视图绑定到架构组件