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 协程与生命周期感知组件一起使用