Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Cómo vincular vistas de diseño con componentes de arquitectura

La biblioteca de AndroidX incluye los componentes de la arquitectura, los cuales se pueden usar para diseñar apps sólidas, que puedan someterse a pruebas y que admitan mantenimiento. La Biblioteca de vinculación de datos funciona a la perfección con los componentes de la arquitectura para simplificar aún más el desarrollo de la IU. Se pueden vincular los diseños de tu app a los datos de los componentes de la arquitectura, que ya te ayudan a administrar el ciclo de vida de los controladores de la IU y a notificar cambios en los datos.

En esta página, se muestra cómo incorporar los componentes de la arquitectura a la app para mejorar aún más los beneficios de usar la biblioteca de vinculación de datos.

Usa LiveData para notificar a la IU los cambios en los datos

Puedes usar objetos LiveData como fuente de vinculación de datos para notificar automáticamente a la IU cambios en los datos. Para obtener más información sobre este componente de la arquitectura, consulta Descripción general de LiveData.

A diferencia de los objetos que implementan Observable, como los campos observables, los objetos LiveData conocen el ciclo de vida de los observadores suscritos a los cambios de datos. Este conocimiento brinda muchos beneficios, que se explican en Las ventajas de usar LiveData. En la versión 3.1 de Android Studio y versiones posteriores, puedes reemplazar los campos observables con objetos LiveData en el código de vinculación de datos.

Para usar un objeto LiveData con tu clase de vinculación, debes especificar un propietario del ciclo de vida a fin de definir el alcance del objeto LiveData. 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:

Kotlin

    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.setLifecycleOwner(this)
        }
    }
    

Java

    class ViewModelActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // Inflate view and obtain an instance of the binding class.
            UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

            // Specify the current activity as the lifecycle owner.
            binding.setLifecycleOwner(this);
        }
    }
    

Puedes utilizar un componente ViewModel, como se explica en Usa ViewModel para administrar datos relacionados con la IU a fin de vincular los datos al diseño. En el componente ViewModel, puedes usar el objeto LiveData para transformar los datos o combinar varias fuentes de datos. En el siguiente ejemplo, se muestra cómo transformar los datos en el ViewModel:

Kotlin

    class ScheduleViewModel : ViewModel() {
        val userName: LiveData

        init {
            val result = Repository.userName
            userName = Transformations.map(result) { result -> result.value }
        }
    }
    

Java

    class ScheduleViewModel extends ViewModel {
        LiveData username;

        public ScheduleViewModel() {
            String result = Repository.userName;
            userName = Transformations.map(result, result -> result.value);
        }
    }
    

Usa ViewModel para administrar datos relacionados con la IU

La biblioteca de vinculación de datos funciona a la perfección con los componentes ViewModel, que exponen los datos que el diseño observa y a cuyos cambios reacciona. Si usas los componentes ViewModel con la biblioteca de vinculación de datos, podrás mover la lógica de IU fuera de los diseños y hacia los componentes, que son más fáciles de probar. La biblioteca de vinculación de datos garantiza que las vistas estén vinculadas y desvinculadas de la fuente de datos cuando sea necesario. La mayor parte del trabajo restante consiste en asegurarse de exponer los datos correctos. Para obtener más información sobre este componente de la arquitectura, consulta la Descripción general de ViewModel.

Para usar el componente ViewModel con la biblioteca de vinculación de datos, debes crear una instancia de tu componente, que hereda de la clase ViewModel; obtener una instancia de la clase de vinculación; y asignar el componente ViewModel a una propiedad en la clase de vinculación. En el siguiente ejemplo, se muestra cómo usar el componente con la biblioteca:

Kotlin

    class ViewModelActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            // Obtain the ViewModel component.
            val userModel: UserModel by viewModels()

            // Inflate view and obtain an instance of the binding class.
            val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)

            // Assign the component to a property in the binding class.
            binding.viewmodel = userModel
        }
    }
    

Java

    class ViewModelActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // Obtain the ViewModel component.
            UserModel userModel = new ViewModelProvider(this).get(UserModel.class);

            // Inflate view and obtain an instance of the binding class.
            UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

            // Assign the component to a property in the binding class.
            binding.viewmodel = userModel;
        }
    }
    

En el diseño, asigna las propiedades y métodos del componente ViewModel a las vistas correspondientes utilizando expresiones de vinculación, como se muestra en el siguiente ejemplo:

<CheckBox
        android:id="@+id/rememberMeCheckBox"
        android:checked="@{viewmodel.rememberMe}"
        android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />
    

Utiliza un ViewModel observable para tener más control sobre los adaptadores de vinculación

Puedes usar un componente ViewModel que implemente el Observable para notificar a otros componentes de la app sobre cambios en los datos, de manera similar a cómo usarías un objeto LiveData.

Hay situaciones en las que podrías preferir usar un componente ViewModel que implemente la interfaz Observable en lugar de usar objetos LiveData, incluso si pierdes las funcionalidades de administración del ciclo de vida de LiveData. Si usas un componente ViewModel que implemente Observable, tendrás más control sobre los adaptadores de vinculación en tu app. Por ejemplo, este patrón brinda más control sobre las notificaciones cuando cambian los datos. También permite especificar un método personalizado para establecer el valor de un atributo en la vinculación de datos bidireccional.

Para implementar un componente ViewModel observable, debes crear una clase que se herede de la clase ViewModel e implemente la interfaz Observable. Puedes proporcionar tu lógica personalizada cuando se suscribe un observador a las notificaciones o se da de baja de ellas utilizando los métodos addOnPropertyChangedCallback() y removeOnPropertyChangedCallback(). También puedes proporcionar lógica personalizada que se ejecute cuando cambien las propiedades del método notifyPropertyChanged(). El siguiente ejemplo de código muestra cómo implementar un ViewModel observable:

Kotlin

    /**
     * A ViewModel that is also an Observable,
     * to be used with the Data Binding Library.
     */
    open class ObservableViewModel : ViewModel(), Observable {
        private val callbacks: PropertyChangeRegistry = PropertyChangeRegistry()

        override fun addOnPropertyChangedCallback(
                callback: Observable.OnPropertyChangedCallback) {
            callbacks.add(callback)
        }

        override fun removeOnPropertyChangedCallback(
                callback: Observable.OnPropertyChangedCallback) {
            callbacks.remove(callback)
        }

        /**
         * Notifies observers that all properties of this instance have changed.
         */
        fun notifyChange() {
            callbacks.notifyCallbacks(this, 0, null)
        }

        /**
         * Notifies observers that a specific property has changed. The getter for the
         * property that changes should be marked with the @Bindable annotation to
         * generate a field in the BR class to be used as the fieldId parameter.
         *
         * @param fieldId The generated BR id for the Bindable field.
         */
        fun notifyPropertyChanged(fieldId: Int) {
            callbacks.notifyCallbacks(this, fieldId, null)
        }
    }
    

Java

    /**
     * A ViewModel that is also an Observable,
     * to be used with the Data Binding Library.
     */
    class ObservableViewModel extends ViewModel implements Observable {
        private PropertyChangeRegistry callbacks = new PropertyChangeRegistry();

        @Override
        protected void addOnPropertyChangedCallback(
                Observable.OnPropertyChangedCallback callback) {
            callbacks.add(callback);
        }

        @Override
        protected void removeOnPropertyChangedCallback(
                Observable.OnPropertyChangedCallback callback) {
            callbacks.remove(callback);
        }

        /**
         * Notifies observers that all properties of this instance have changed.
         */
        void notifyChange() {
            callbacks.notifyCallbacks(this, 0, null);
        }

        /**
         * Notifies observers that a specific property has changed. The getter for the
         * property that changes should be marked with the @Bindable annotation to
         * generate a field in the BR class to be used as the fieldId parameter.
         *
         * @param fieldId The generated BR id for the Bindable field.
         */
        void notifyPropertyChanged(int fieldId) {
            callbacks.notifyCallbacks(this, fieldId, null);
        }
    }
    

Recursos adicionales

Para obtener más información sobre la vinculación de datos, consulta los siguientes recursos adicionales.

Ejemplos

Codelabs

Entradas de blog