Библиотека AndroidX включает компоненты архитектуры, которые можно использовать для разработки надежных, тестируемых и поддерживаемых приложений. Библиотека привязки данных работает в связке с компонентами архитектуры, что ещё больше упрощает разработку интерфейса. Макеты в приложении можно привязать к данным в компонентах архитектуры, которые помогают управлять жизненным циклом контроллера пользовательского интерфейса и уведомлять пользовательский интерфейс об изменениях в данных.
На этой странице показано, как включить компоненты архитектуры в ваше приложение, чтобы максимально эффективно использовать библиотеку привязки данных.
Используйте LiveData, чтобы уведомлять интерфейс об изменениях данных
Объекты LiveData можно использовать в качестве источника привязки данных, чтобы автоматически уведомлять интерфейс об изменениях в данных. Подробнее об этом компоненте архитектуры…
В отличие от объектов, реализующих Observable, например наблюдаемых полей, объекты LiveData знают о жизненном цикле наблюдателей, подписанных на изменения данных. Это дает множество преимуществ, которые описаны в разделе Преимущества использования LiveData.
В Android Studio версии 3.1 и выше вы можете заменить наблюдаемые поля объектами LiveData в коде привязки данных.
Чтобы использовать объект LiveData с классом привязки, необходимо указать владельца жизненного цикла, который будет определять область действия объекта LiveData. В следующем примере действие указывается как владелец жизненного цикла после создания экземпляра класса привязки:
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); } }
Чтобы связать данные с макетом, можно использовать компонент ViewModel, как описано в следующем разделе. В компоненте ViewModel можно использовать объект LiveData, чтобы преобразовывать данные или объединять несколько источников данных. В примере ниже показано, как преобразовать данные в 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); } }
Используйте ViewModel для управления данными, связанными с пользовательским интерфейсом
Библиотека привязки данных без проблем работает с компонентами ViewModel. ViewModel предоставляет данные, которые отслеживает макет, и реагирует на их изменения. Использование компонентов ViewModel с библиотекой привязки данных позволяет перенести логику пользовательского интерфейса из макетов в компоненты, которые проще тестировать. Библиотека привязки данных гарантирует, что представления привязываются и отвязываются от источника данных по мере необходимости. Вам останется только убедиться, что вы предоставляете правильные данные. Подробнее об этом компоненте архитектуры можно узнать в обзоре ViewModel.
Чтобы использовать компонент ViewModel с библиотекой привязки данных, необходимо создать экземпляр компонента, который наследует от класса ViewModel, получить экземпляр класса привязки и назначить компонент ViewModel свойству в классе привязки. В примере ниже показано, как использовать компонент с библиотекой:
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; } }
В макете назначьте свойства и методы компонента ViewModel соответствующим представлениям, используя выражения привязки, как показано в следующем примере:
<CheckBox
android:id="@+id/rememberMeCheckBox"
android:checked="@{viewmodel.rememberMe}"
android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />
Используйте Observable ViewModel для большего контроля над адаптерами привязки
Вы можете использовать компонент ViewModel, который реализует интерфейс Observable, чтобы уведомлять другие компоненты приложения об изменениях в данных, как и в случае с объектом LiveData.
В некоторых случаях лучше использовать компонент ViewModel, реализующий интерфейс Observable, а не объекты LiveData, даже если вы потеряете возможности управления жизненным циклом, которые предоставляет LiveData. Использование компонента ViewModel, реализующего Observable, дает вам больше контроля над адаптерами привязки в вашем приложении. Например, этот шаблон дает вам больше контроля над уведомлениями при изменении данных; он также позволяет указать собственный метод для установки значения атрибута в двусторонней привязке данных.
Чтобы реализовать наблюдаемый компонент ViewModel, создайте класс, наследующий от класса ViewModel и реализующий интерфейс Observable. Вы можете задать собственную логику для подписки наблюдателя на уведомления и отмены подписки с помощью методов addOnPropertyChangedCallback() и removeOnPropertyChangedCallback(). Вы также можете задать собственную логику, которая будет выполняться при изменении свойств в методе notifyPropertyChanged(). В следующем примере кода показано, как реализовать наблюдаемый объект ViewModel:
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 must 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 must 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); } }
Дополнительные ресурсы
Чтобы узнать больше о привязке данных, ознакомьтесь со следующими дополнительными ресурсами.
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Как работать с объектами наблюдаемых данных
- Загрузка и отображение данных с разбивкой по страницам
- Как использовать сопрограммы Kotlin с компонентами, учитывающими жизненный цикл