La observabilidad es la capacidad de un objeto para notificar a otros sobre cambios en sus datos. La biblioteca de vinculación de datos te permite hacer que objetos, campos o colecciones sean observables.
Se puede usar cualquier objeto para la vinculación de datos, pero modificar el objeto no hace que la IU se actualice automáticamente. La vinculación de datos se puede utilizar para otorgar a los objetos de datos la capacidad de notificar a otros objetos, conocidos como objetos de escucha, cuando cambian sus datos. Hay tres tipos diferentes de clases observables: objetos, campos y colecciones.
Cuando uno de esos objetos de datos observables está vinculado a la IU y una propiedad del objeto de datos cambia, la IU se actualiza automáticamente.
Campos observables
Crear clases que implementen la interfaz Observable
requiere un poco de trabajo. Hacerlo no valdría la pena si las clases solo tuvieran unas pocas propiedades. En este caso, puedes usar la clase genérica Observable
y las siguientes clases primitivas específicas para que los campos sean observables:
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
Los campos observables son objetos observables autónomos que tienen un solo campo. Las versiones primitivas evitan la conversión boxing y unboxing durante las operaciones de acceso. Para usar este mecanismo, crea una propiedad public final
en el lenguaje de programación Java o una propiedad de solo lectura en Kotlin, como se muestra en el siguiente ejemplo:
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(); }
Para acceder al valor del campo, usa los métodos de acceso set()
y get()
, o bien la sintaxis de la propiedad Kotlin:
Kotlin
user.firstName = "Google" val age = user.age
Java
user.firstName.set("Google"); int age = user.age.get();
Colecciones observables
Algunas apps usan estructuras dinámicas para almacenar datos. Las colecciones observables permiten acceder a esas estructuras mediante una clave. La clase ObservableArrayMap
es útil cuando la clave es un tipo de referencia (por ejemplo, String
), como se muestra en el siguiente ejemplo:
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);
En el diseño, se puede encontrar el mapa utilizando las claves de string de la siguiente manera:
<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"/>
La clase ObservableArrayList
es útil cuando la clave es un número entero, por ejemplo:
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);
En el diseño, se puede acceder a la lista por medio de los índices, como se muestra en el siguiente ejemplo:
<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"/>
Objetos observables
Una clase que implementa la interfaz Observable
permite registrar objetos de escucha que desean recibir notificaciones de cambios de propiedad en el objeto observable.
La interfaz Observable
tiene un mecanismo para agregar y quitar objetos de escucha, pero debes decidir cuándo se envían las notificaciones. Para facilitar el desarrollo, la biblioteca de vinculación de datos proporciona la clase BaseObservable
, que implementa el mecanismo de registro del objeto de escucha. La clase de datos que implementa BaseObservable
es responsable de notificar cuándo cambian las propiedades. Para ello, asigna una anotación Bindable
al método get y llama al método notifyPropertyChanged()
en el método set, como se muestra en el siguiente ejemplo:
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); } }
La vinculación de datos genera una clase denominada BR
en el paquete del módulo que contiene los ID de los recursos utilizados para la vinculación de datos. La anotación Bindable
genera una entrada en el archivo de la clase BR
durante la compilación. Si no se puede cambiar la clase base para las clases de datos, se puede implementar la interfaz Observable
utilizando un objeto PropertyChangeRegistry
a fin de registrar y notificar a los objetos de escucha de manera eficiente.
Recursos adicionales
Para obtener más información sobre la vinculación de datos, consulta los siguientes recursos adicionales.