AndroidX庫(kù)包含架構(gòu)組件,您可以使用它來(lái)設(shè)計(jì)健壯痛悯,可測(cè)試和可維護(hù)的應(yīng)用程序余黎。 數(shù)據(jù)綁定庫(kù)可與架構(gòu)組件無(wú)縫協(xié)作,進(jìn)一步簡(jiǎn)化UI的開(kāi)發(fā)载萌。 應(yīng)用程序中的布局可以綁定到體系結(jié)構(gòu)組件中的數(shù)據(jù)惧财,這些數(shù)據(jù)已經(jīng)幫助您管理UI控制器生命周期并通知數(shù)據(jù)中的更改。
此頁(yè)面顯示如何將架構(gòu)組件合并到您的應(yīng)用程序扭仁,以進(jìn)一步增強(qiáng)使用數(shù)據(jù)綁定庫(kù)的好處垮衷。
一、使用LiveData通知UI有關(guān)數(shù)據(jù)更改的信息
您可以使用LiveData對(duì)象作為數(shù)據(jù)綁定源斋枢,以自動(dòng)通知UI有關(guān)數(shù)據(jù)更改的信息帘靡。 有關(guān)此體系結(jié)構(gòu)組件的更多信息,請(qǐng)參閱LiveData概述瓤帚。
與實(shí)現(xiàn)Observable的對(duì)象(例如可觀察字段)不同描姚,LiveData對(duì)象了解訂閱數(shù)據(jù)更改的觀察者的生命周期涩赢。 這些知識(shí)帶來(lái)了許多好處,使用LiveData的優(yōu)勢(shì)對(duì)此進(jìn)行了解釋轩勘。 在Android Studio 3.1及更高版本中筒扒,您可以使用數(shù)據(jù)綁定代碼中的LiveData對(duì)象替換可觀察字段。
要將LiveData對(duì)象與綁定類(lèi)一起使用绊寻,需要指定生命周期所有者以定義LiveData對(duì)象的范圍花墩。 以下示例在實(shí)例化綁定類(lèi)之后將活動(dòng)指定為生命周期所有者:
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中所述來(lái)管理與UI相關(guān)的數(shù)據(jù)),以將數(shù)據(jù)綁定到布局澄步。 在ViewModel組件中冰蘑,您可以使用LiveData對(duì)象轉(zhuǎn)換數(shù)據(jù)或合并多個(gè)數(shù)據(jù)源。 以下示例顯示如何轉(zhuǎn)換ViewModel中的數(shù)據(jù):
class ScheduleViewModel extends ViewModel {
LiveData username;
public ScheduleViewModel() {
String result = Repository.userName;
userName = Transformations.map(result, result -> result.value);
}
二村缸、使用ViewModel管理與UI相關(guān)的數(shù)據(jù)
數(shù)據(jù)綁定庫(kù)與ViewModel組件無(wú)縫協(xié)作祠肥,后者顯示布局觀察到的數(shù)據(jù)并對(duì)其更改做出反應(yīng)。 將ViewModel組件與數(shù)據(jù)綁定庫(kù)一起使用梯皿,可以將UI邏輯從布局移動(dòng)到組件中仇箱,這些組件更易于測(cè)試。 數(shù)據(jù)綁定庫(kù)可確保在需要時(shí)綁定和取消綁定數(shù)據(jù)源东羹。 剩下的大部分工作都在于確保您公開(kāi)正確的數(shù)據(jù)剂桥。 有關(guān)此體系結(jié)構(gòu)組件的更多信息,請(qǐng)參閱ViewModel概述属提。
要將ViewModel組件與數(shù)據(jù)綁定庫(kù)一起使用权逗,必須實(shí)例化從Viewmodel類(lèi)繼承的組件,獲取綁定類(lèi)的實(shí)例垒拢,并將ViewModel組件分配給綁定類(lèi)中的屬性旬迹。 以下示例顯示如何將該組件與庫(kù)一起使用:
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;
}
}
在布局中火惊,使用綁定表達(dá)式將ViewModel組件的屬性和方法分配給相應(yīng)的視圖求类,如以下示例所示:
<CheckBox
android:id="@+id/rememberMeCheckBox"
android:checked="@{viewmodel.rememberMe}"
android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />
三、使用Observable ViewModel可以更好地控制綁定適配器
您可以使用實(shí)現(xiàn)Observable的ViewModel組件來(lái)通知其他應(yīng)用程序組件有關(guān)數(shù)據(jù)更改的信息屹耐,類(lèi)似于使用LiveData對(duì)象的方式尸疆。
在某些情況下,您可能更喜歡使用ViewModel組件來(lái)實(shí)現(xiàn)Observable接口而不是使用LiveData對(duì)象惶岭,即使您丟失了LiveData的生命周期管理功能寿弱。使用實(shí)現(xiàn)Observable的ViewModel組件可以更好地控制應(yīng)用程序中的綁定適配器。例如按灶,此模式使您可以在數(shù)據(jù)更改時(shí)更好地控制通知症革,還允許您指定自定義方法以在雙向數(shù)據(jù)綁定中設(shè)置屬性的值。
要實(shí)現(xiàn)可觀察的ViewModel組件鸯旁,必須創(chuàng)建一個(gè)繼承自ViewModel類(lèi)并實(shí)現(xiàn)Observable接口的類(lèi)噪矛。當(dāng)觀察者使用addOnPropertyChangedCallback()和removeOnPropertyChangedCallback()方法訂閱或取消訂閱通知時(shí)量蕊,您可以提供自定義邏輯。您還可以提供在notifyPropertyChanged()方法中屬性更改時(shí)運(yùn)行的自定義邏輯艇挨。以下代碼示例演示如何實(shí)現(xiàn)可觀察的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);
}
}