AndroidX 库包含您可以用来设计强大、可测试且易于维护的应用的架构组件。数据绑定库与架构组件无缝协作,进一步简化了 UI 开发。应用中的布局可以绑定到架构组件中的数据,这有助于您管理 UI 控制器的生命周期并通知 UI 数据中的更改。
此页面介绍如何将架构组件整合到您的应用中,以充分利用数据绑定库。
使用 LiveData 通知 UI 数据更改
您可以使用LiveData
对象作为数据绑定源,以自动通知 UI 数据中的更改。有关此架构组件的更多信息,请参阅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 管理与 UI 相关的数据
数据绑定库与ViewModel
组件无缝协作。ViewModel
公开布局观察到的数据并对其更改做出反应。使用数据绑定库的ViewModel
组件,您可以将 UI 逻辑从布局移到组件中,这些组件更易于测试。数据绑定库确保在需要时绑定和解绑视图与数据源。大部分剩余工作包括确保您公开了正确的数据。有关此架构组件的更多信息,请参阅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()}" />
使用可观察的ViewModel可以更好地控制绑定适配器。
您可以使用实现Observable
接口的ViewModel
组件来通知其他应用程序组件数据变化,类似于使用LiveData
对象。
在某些情况下,您可能更倾向于使用实现Observable
接口的ViewModel
组件,而不是使用LiveData
对象,即使您会失去LiveData
的生命周期管理功能。使用实现Observable
接口的ViewModel
组件,可以更好地控制应用程序中的绑定适配器。例如,此模式可以更好地控制数据更改时的通知;它还可以让您指定一个自定义方法来设置双向数据绑定中属性的值。
要实现可观察的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 协程与生命周期感知组件一起使用