Cómo trabajar con objetos de datos observables

La observabilidad es la capacidad de un objeto de notificar a otros sobre cambios en sus datos. La biblioteca de vinculación de datos te permite crear objetos, campos o de datos observables.

Puedes usar cualquier objeto para la vinculación de datos, pero modificar el objeto no hace que la IU se actualice automáticamente. Puedes usar la vinculación de datos para asignar tus datos a los objetos la capacidad de notificar a otros objetos, conocidos como objetos de escucha, cuando los cambios en sus datos. Hay tres tipos de clases observables: campos, colecciones y objetos.

Cuando uno de estos objetos de datos observables está vinculado a la IU y a una propiedad de cuando el objeto de datos cambia, la IU se actualiza automáticamente.

Campos observables

Si tus clases solo tienen unas pocas propiedades, puede que no valga la pena el esfuerzo crear clases que implementen el Observable. En este En este caso, puedes usar la clase genérica Observable y las siguientes clases primitivas específicas para hacer que los campos sean observables:

Los campos observables son objetos observables autónomos que tienen un solo . Las versiones primitivas evitan boxing y unboxing durante el acceso las operaciones. Para usar este mecanismo, crea una propiedad public final en Java. lenguaje de programación 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 el set() y Métodos de acceso get() o usa la propiedad Kotlin sintaxis:

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 acceso a estas estructuras con una clave. El Clase ObservableArrayMap es útil cuando la clave es un tipo de referencia, como String, tal como se muestra en la 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, puedes encontrar el mapa usando las claves de cadena, como se muestra en el siguiente ejemplo:

<data>
    <import type="android.databinding.ObservableMap"/>
    <variable name="user" type="ObservableMap&lt;String, Object&gt;"/>
</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 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, puedes acceder a la lista a través 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&lt;Object&gt;"/>
</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 el registro de objetos de escucha que desean recibir notificaciones sobre cambios de propiedades desde el .

La interfaz Observable tiene un mecanismo para agregar y quitar objetos de escucha, pero puedes decidir cuándo se envían las notificaciones. Para facilitar el desarrollo, el panel de La biblioteca de vinculación proporciona el BaseObservable, que implementa el mecanismo de registro de objetos de escucha. La clase de datos que implementa BaseObservable es responsable de notificar cuándo cambian las propiedades. Tareas pendientes esto, 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 llamada 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 clase BR durante la compilación. Si la clase base de las clases de datos, puedes implementar la interfaz Observable con un PropertyChangeRegistry se registre y notifique a los objetos de escucha de manera eficiente.

Objetos optimizados para ciclos de vida

Los diseños de tu app también pueden vincularse a fuentes de vinculación de datos que notificar a la IU sobre cambios en los datos. De esa manera, tus vinculaciones están optimizados para ciclos de vida y solo se activan cuando la IU es visible en la pantalla.

Compatible con la vinculación de datos StateFlow y LiveData Para obtener más información Usa LiveData en la vinculación de datos; consulta Usa LiveData para notificar a la IU sobre los datos de la configuración.

Usa StateFlow

Si tu app usa Kotlin con corrutinas, puedes usar Objetos StateFlow como fuente de vinculación de datos Para usar un objeto StateFlow con tu clase de vinculación, especifica un propietario del ciclo de vida para definir el alcance del StateFlow. En el siguiente ejemplo, se especifica la actividad como el Propietario del ciclo de vida después de que se crea una instancia de la clase de vinculación:

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
    }
}

Como se describe en Vincula vistas de diseño a arquitectura Componentes, vinculación de datos funciona a la perfección con ViewModel objetos. Puedes usar StateFlow y ViewModel juntos de la siguiente manera:

class ScheduleViewModel : ViewModel() {

    private val _username = MutableStateFlow<String>("")
    val username: StateFlow<String> = _username

    init {
        viewModelScope.launch {
            _username.value = Repository.loadUserName()
        }
    }
}

En el diseño, asigna las propiedades y los métodos del objeto ViewModel a las vistas correspondientes usando expresiones de vinculación, como se muestra a continuación ejemplo:

<TextView
    android:id="@+id/name"
    android:text="@{viewmodel.username}" />

La IU se actualiza automáticamente cada vez que cambia el valor del nombre del usuario.

Inhabilita la compatibilidad con StateFlow

En el caso de las apps que usan Kotlin y AndroidX, la compatibilidad con StateFlow se realiza automáticamente que se incluye con la vinculación de datos. Esto significa que la dependencia de las corrutinas se incluirá automáticamente en tu app si la dependencia aún no está disponible.

Para inhabilitar esta función, agrega lo siguiente a tu Archivo build.gradle:

Groovy

android {
    ...
    dataBinding {
        addKtx = false
    }
}

Kotlin

android {
    ...
    dataBinding {
        addKtx = false
    }
}

Como alternativa, puedes agregar StateFlow de forma global en tu proyecto para inhabilitarlo de manera global. la siguiente línea al archivo gradle.properties:

Groovy

android.defaults.databinding.addKtx = false

Kotlin

android.defaults.databinding.addKtx = false

Recursos adicionales

Si deseas obtener más información sobre la vinculación de datos, consulta los siguientes vínculos para obtener recursos adicionales:

Ejemplos

Codelabs

Entradas de blog