Con la vinculación de datos unidireccional, puedes definir un valor en un atributo y definir una objeto de escucha que reacciona a un cambio en ese atributo:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@{viewmodel.rememberMe}" android:onCheckedChanged="@{viewmodel.rememberMeChanged}" />
La vinculación de datos bidireccional proporciona un acceso directo a este proceso:
<CheckBox android:id="@+id/rememberMeCheckBox" android:checked="@={viewmodel.rememberMe}" />
La notación @={}
, que incluye el signo "=" recibe los datos
cambios en la propiedad y escuchar las actualizaciones de los usuarios al mismo tiempo.
Para reaccionar a los cambios en los datos de la copia de seguridad, puedes hacer que tu diseño
una implementación de Observable
, que suele
BaseObservable
y usa un
@Bindable
, como se muestra en
el siguiente fragmento de código:
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); } } }
Debido a que el método get de la propiedad vinculante se llama getRememberMe()
, el
el método set correspondiente de la propiedad usa automáticamente el nombre
setRememberMe()
Para obtener más información sobre el uso de BaseObservable
y @Bindable
, consulta Trabaja con
objetos de datos observables.
Vinculación de datos bidireccional con atributos personalizados
La plataforma proporciona implementaciones de vinculación de datos bidireccional para las
bidireccionales y cambiar objetos de escucha, que puedes usar
como parte de tu app. Si quieres usar la vinculación de datos bidireccional con los
atributos, debes trabajar con el
@InverseBindingAdapter
y
@InverseBindingMethod
anotaciones.
Por ejemplo, si quieres habilitar la vinculación de datos bidireccional en un atributo "time"
En una vista personalizada llamada MyView
, completa los siguientes pasos:
Anota el método que establece el valor inicial y se actualiza cuando el valor Cambios con
@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; } }
Anota el método que lee el valor de la vista usando
@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(); }
En este punto, la vinculación de datos sabe qué hacer cuando los datos cambian (llama a
método anotado con
@BindingAdapter
) y qué
cuando cambia el atributo de vista (llama a
InverseBindingListener
).
Sin embargo, no sabe cuándo ni cómo cambia el atributo.
Para eso, necesitas establecer un objeto de escucha en la vista. Puede ser un objeto de escucha personalizado
asociada con tu vista personalizada, o puede ser un evento genérico, como una pérdida
de enfoque o un cambio de texto. Agrega la anotación @BindingAdapter
al método
que configura el objeto de escucha para los cambios en la propiedad:
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. }
El objeto de escucha incluye un InverseBindingListener
como parámetro. Se usa el
InverseBindingListener
para indicarle al sistema de vinculación de datos que el atributo tiene
cambió. Luego, el sistema puede comenzar a llamar al método anotado usando
@InverseBindingAdapter
, etcétera.
En la práctica, este objeto de escucha incluye una lógica no trivial, incluidos los objetos de escucha
para la vinculación de datos unidireccional. Para ver un ejemplo, consulta el adaptador del atributo de texto.
cambio,
TextViewBindingAdapter
Converters
Si la variable que está vinculada a un objeto View
debe formatearse, traducirse o cambiarse de alguna manera antes de mostrarse,
es posible usar un objeto Converter
.
Por ejemplo, toma un objeto EditText
que muestra una fecha:
<EditText
android:id="@+id/birth_date"
android:text="@={Converter.dateToString(viewmodel.birthDate)}"
/>
El atributo viewmodel.birthDate
contiene un valor de tipo Long
, por lo que debe
formateados con un convertidor.
Debido a que se usa una expresión bidireccional, también debe haber una inversión
converter para que la biblioteca sepa cómo volver a convertir la string proporcionada por el usuario
al tipo de datos de copia de seguridad, en este caso, Long
. Este proceso se realiza agregando
la anotación @InverseMethod
en uno de los convertidores y hacer que esta anotación haga referencia a la inversa
convertidor. En el siguiente código, aparece un ejemplo de esta configuración
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. } }
Bucles infinitos con vinculación de datos bidireccional
Ten cuidado de no introducir bucles infinitos cuando uses la vinculación de datos bidireccional. Cuándo
el usuario cambia un atributo, el método anotado usando
Se llama a @InverseBindingAdapter
y se asigna el valor a la copia de seguridad
propiedad. Esto, a su vez, llamaría al método anotado usando
@BindingAdapter
, que activaría otra llamada al método anotado
usando @InverseBindingAdapter
, etcétera.
Por este motivo, es importante romper posibles bucles infinitos comparando
valores nuevos y antiguos en los métodos anotados con @BindingAdapter
.
Atributos bidireccionales
La plataforma brinda compatibilidad integrada con la vinculación de datos bidireccional cuando se usa los atributos de la siguiente tabla. Para obtener detalles sobre cómo la plataforma proporciona esta compatibilidad, consulta las implementaciones para los adaptadores de vinculación correspondientes:
Clase | Atributo(s) | Adaptador de vinculación |
---|---|---|
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
|
Recursos adicionales
Para obtener más información sobre la vinculación de datos, consulta los siguientes vínculos: recursos adicionales.
Ejemplos
Codelabs
Entradas de blog
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Cómo trabajar con objetos de datos observables
- Diseños y expresiones vinculantes
- Cómo vincular vistas de diseño con componentes de arquitectura