Библиотека AndroidX включает компоненты архитектуры , которые можно использовать для разработки надежных, тестируемых и поддерживаемых приложений. Библиотека привязки данных безупречно работает с компонентами архитектуры, что еще больше упрощает разработку пользовательского интерфейса. Макеты в вашем приложении могут быть привязаны к данным в компонентах архитектуры, что помогает вам управлять жизненным циклом контроллера пользовательского интерфейса и уведомлять пользовательский интерфейс об изменениях в данных.
На этой странице показано, как включить компоненты архитектуры в ваше приложение, чтобы максимально эффективно использовать библиотеку привязки данных.
Используйте LiveData для уведомления пользовательского интерфейса об изменениях данных.
Вы можете использовать объекты LiveData
в качестве источника привязки данных для автоматического уведомления пользовательского интерфейса об изменениях в данных. Дополнительную информацию об этом компоненте архитектуры см. в обзоре LiveData .
В отличие от объектов, реализующих Observable
, например наблюдаемых полей , объекты LiveData
знают о жизненном цикле наблюдателей, подписавшихся на изменения данных. Эти знания дают множество преимуществ, которые описаны в разделе «Преимущества использования LiveData» . В Android Studio версии 3.1 и выше вы можете заменить наблюдаемые поля объектами LiveData
в коде привязки данных.
Чтобы использовать объект LiveData
с классом привязки, вам необходимо указать владельца жизненного цикла, чтобы определить область действия объекта LiveData
. В следующем примере действие указывается в качестве владельца жизненного цикла после создания экземпляра класса привязки:
Котлин
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) } }
Ява
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
:
Котлин
class ScheduleViewModel : ViewModel() { val userName: LiveDatainit { val result = Repository.userName userName = Transformations.map(result) { result -> result.value } } }
Ява
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
свойству в классе привязки. В следующем примере показано, как использовать компонент с библиотекой:
Котлин
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 } }
Ява
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
:
Котлин
/** * 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) } }
Ява
/** * 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 с компонентами, учитывающими жизненный цикл.