AndroidX库包含了架构组件,你可以用它设计出鲁棒的,可测试的和可维护的app。数据绑定库与架构组件无缝协作,以进一步简化UI的开发。在你的app布局文件中能绑定架构组件的数据,它已经帮助你管理UI controllers的生命周期和在数据改变时通知UI controllers。
这篇文章展示了如何将架构组件合并到你的应用程序中,以进一步增强使用数据绑定库的好处。
使用LiveData在数据改变时去通知UI
你能使用LiveData
对象作为数据绑源,在数据发生改变时去自动地通知UI。关于这个架构组件的更多信息请看,Live Data Overview。
与实现了Observable
接口的对象(比如observable fields)不同,LiveData
对象知道订阅数据观察者的生命周期。这一点就体现了LiveData的优越性The advantages of using LiveData。在Android Studio3.1或者更高的版本中,你可以在你的数据绑定代码中用LiveData
去替换observable fields
。
为了使用LiveData对象在你的绑定类中,你需要指定一个生命周期所有者来定义LiveData对象的范围。
下面的例子指定了当绑定类被实例化后的生命周期所有者:
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管理你的与UI相关的数据)去绑定数据到布局文件中。在ViewModel
组件中,你可以使用LiveData
对象转化数据或者合并多样的数据源。下面的例子展示了在ViewModel中如何转化数据:
class ScheduleViewModel extends ViewModel {
LiveData username;
public ScheduleViewModel() {
String result = Repository.userName;
userName = Transformations.map(result, result -> result.value);
}
使用ViewModel管理与UI相关的数据
数据绑定库与ViewModel组件可以无缝的工作,它暴露了布局所观察到的数据并可以对其变化作出反应。使用数据绑定库的ViewModel
组件允许你将UI逻辑移除布局文件,并且移入控件中,这将有助于你进行测试。数据绑定库确保了在需要时将view与data进行绑定与解绑。剩下的大部分工作都是确保你暴露了正确的数据。更过的关于架构组件的信息,请看ViewModel Overview。
在数据绑定库中使用ViewModel
组件,你必须初始化你的组件(它继承与ViewModel
类)获取一个你的绑定类的实例,并且给你的ViewModel组件分配一个绑定类中的属性。下面的代码展示了怎样使用数据绑定库里的这个组件:
class ViewModelActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Obtain the ViewModel component.
UserModel userModel = ViewModelProviders.of(getActivity())
.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组件去通知另一个app组件,当然你也可以使用LiveData
对象。
有几种情况也许可以让你更倾向于使用实现了Observable接口的ViewModel组件,而不是使用LiveData
对象,即使你会失去LiveData的管理生命周期的能力。在你的app中,使用实现了Observable接口的ViewModel组件可以让你控制更多的绑定适配器。例如,当数据发生变化时,这种模式使你能够更好地控制通知,它还允许你指定一个定制方法来在双向数据绑定中设置属性的值。
为了实现可观察的ViewModel组件,你必须创建一个继承于ViewModel的类,并且实现Observable接口。当一个观察者订阅或者解订阅时,你可以使用addOnPropertyChangedCallback()
和removeOnPropertyChangedCallback()
方法提供你自定义的逻辑去通知。你也可以提供自定义的逻辑,并且在notifyPropertyChanged()
方法中属性改变时运行。下面的代码展示了怎样实现一个可观察的ViewModel:
/**
* 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);
}
}