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: LiveDatainit { val result = Repository.userName userName = Transformations.map(result) { result -> result.value } } }
Java
class ScheduleViewModel extends ViewModel { LiveDatausername; 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.