ViewModel介紹
關(guān)于ViewModel分瘾,根據(jù)官網(wǎng)開發(fā)文檔介紹,它可以管理界面控制器(如 Activity 和 Fragment)的生命周期紊婉。Android 框架可能會決定銷毀或重新創(chuàng)建界面控制器药版,以響應(yīng)完全不受您控制的某些用戶操作或設(shè)備事件。意思就是比如當Activity銷毀或者重新創(chuàng)建的時候(比如屏幕選擇)喻犁,因配置更改而重新創(chuàng)建 Activity 后槽片,新 Activity 必須重新提取用戶列表。對于簡單的數(shù)據(jù)肢础,Activity 可以使用onSaveInstanceState()
和onCreate()
進行數(shù)據(jù)恢復(fù)还栓。但是,一些較大的數(shù)據(jù)传轰,就不太適合用通常的方法來進行恢復(fù)了囊陡。而ViewModel就可以幫助我們來解決這個問題敷存。
LiveData介紹
根據(jù)官網(wǎng)開發(fā)文檔說明财松,它是一個可以感知生命周期痴脾,就是和LifeCycle綁定的一個數(shù)據(jù)存儲類,而且LiveData遵照觀察者模式期贫,當生命周期發(fā)生變化的時候跟匆,LiveData就會通知被觀察的那些對象,這樣就可以實現(xiàn)實時更新界面數(shù)據(jù)了通砍,而且在生命周期結(jié)束的時候玛臂,也會自動進行銷毀,因為通過LifeCycle進行綁定了埠帕,這樣也不會發(fā)生內(nèi)存泄露垢揩,也就不需要手動去處理生命周期的那些事件了。
ViewModel的基本使用
老樣子,首先導(dǎo)入依賴斑匪,參考官方導(dǎo)入說明呐籽。
其實關(guān)于ViewModel和LiveData的基本使用,其實官網(wǎng)說明的很清楚了蚀瘸,我這里只是基本介紹一下狡蝶,首先是在Activity中使用,我們需要創(chuàng)建一個類來繼承ViewModel贮勃,這里的MutableLiveData其實就是Jetpack的另一個架構(gòu)組件LiveData組件贪惹,具體用法我稍后再說。
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> list;
public LiveData<List<User>> getUsers() {
if (list == null) {
list = new MutableLiveData<>();
loadUsers();
}
return list;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
User user = new User();
user.setName("測試");
List<User> users = new ArrayList<>();
users.add(user);
list.setValue(users);
}
}
//JavaBean
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在Activity中寂嘉,我們通過ViewModelProviders來獲取和調(diào)用需要的ViewModel就好了奏瞬,代碼如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView;
textView = findViewById(R.id.test);
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(List<User> users) {
textView.setText(users.get(0).getName());
}
});
}
}
Fragment數(shù)據(jù)共享
兩個Activity之間或者Fragment之間傳遞數(shù)據(jù)是很經(jīng)常的事情枫绅,一般傳遞數(shù)據(jù)之間我們不是通過Intent,要不就是通過Bundle來進行數(shù)據(jù)的傳遞硼端,我們其實也可以通過ViewModel來進行數(shù)據(jù)的傳遞并淋,舉個例子,比如在一個Fragment單擊一個控件珍昨,然后進行數(shù)據(jù)傳遞县耽,這個數(shù)據(jù)會顯示在第二個Fragment上面,首先修改一下ViewModel
public class MyViewModel extends ViewModel {
private MutableLiveData<User> model = new MutableLiveData<>();
public void select(User user){
model.setValue(user);
}
public User getSelect(){
return model.getValue();
}
}
然后在兩個Fragment中分別設(shè)置和獲取镣典,代碼如下:
private MyViewModel myViewModel;
private void initView(View root) {
root.findViewById(R.id.text_home).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
User user = new User();
user.setName("傳遞Fragment");
myViewModel.select(user);
Toast.makeText(getActivity(),"已點擊",Toast.LENGTH_SHORT).show();
}
});
}
然后在要獲取的Fragment中進行獲取就好了兔毙,通過getSelect()
方法。
final TextView textView = root.findViewById(R.id.text_dashboard);
myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
textView.setText(myViewModel.getSelect().getName());
ViewModel的生命周期
ViewModel對象存在的時間范圍是獲取ViewModel時傳遞給ViewModelProvider的Lifecycle瞒御。ViewModel將一直留在內(nèi)存中,直到限定其存在時間范圍的Lifecycle永久消失:對于Activity神郊,是在Activity完成時肴裙;而對于Fragment,是在Fragment分離時涌乳。而且蜻懦,通過ViewModel里的LiveData組件進行配合使用,還可以跟跟LifeCycle所進行關(guān)聯(lián)夕晓,當調(diào)用LiveData的
observe()
進行更新的時候宛乃,就可以進行生命周期的感知了。ViewModel存在的時間范圍是從您首次請求ViewModel直到Activity完成并銷毀蒸辆。LiveData的基本使用
在ViewModel中征炼,其實已經(jīng)用到了LiveData,我們用的是MutableLiveData躬贡,它是LiveData的實現(xiàn)類谆奥,LiveData 是一個抽象類,它的實現(xiàn)子類有 MutableLiveData 拂玻,MediatorLiveData酸些。在實際使用中,用得比較多的是 MutableLiveData檐蚜。他常常結(jié)合 ViewModel 一起使用魄懂。LiveData的使用方法也很簡單。
private MutableLiveData<String> mNameEvent = new MutableLiveData<>();
而進行監(jiān)聽的話闯第,其實剛剛在ViewModel的基本使用中也說過了市栗。
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> list = new MutableLiveData<>();
public void setList(MutableLiveData<List<User>> list) {
this.list = list;
}
public MutableLiveData<List<User>> getList() {
return list;
}
}
//進行調(diào)用
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getList().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(List<User> users) {
textView.setText(users.get(0).getName());
}
});
如果說你想要傳入?yún)?shù)的話,ViewModelProvider.of還有一個構(gòu)造方法,它要傳入的值就是ViewModelProvider.Factory填帽,它是一個接口蛛淋,我們可以這么寫。
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> list = new MutableLiveData<>();
public MyViewModel(String key){
User user = new User();
user.setName(key);
list.setValue(new ArrayList<User>());
list.getValue().add(user);
}
public void setList(MutableLiveData<List<User>> list) {
this.list = list;
}
public MutableLiveData<List<User>> getList() {
return list;
}
public static class Factory implements ViewModelProvider.Factory {
private String key;
public Factory(String key) {
this.key = key;
}
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) new MyViewModel(key);
}
}
}
然后直接調(diào)用就好了
//第二個參數(shù)進行傳入
MyViewModel model = ViewModelProviders.of(this, new MyViewModel.Factory("key")).get(MyViewModel.class);
model.getList().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(List<User> users) {
textView.setText(users.get(0).getName());
}
});
關(guān)于自定義LiveData
public class UserLiveData extends LiveData<User> {
//監(jiān)聽數(shù)據(jù)
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super User> observer) {
super.observe(owner, observer);
}
//onPause 盲赊,onStop铣鹏, onDestroy 也會調(diào)用onChanged的回調(diào)。
@Override
public void observeForever(@NonNull Observer<? super User> observer) {
super.observeForever(observer);
}
//回調(diào)該方法時哀蘑,表示LiveData正在被使用诚卸。
@Override
protected void onActive() {
super.onActive();
}
//回調(diào)該方法時,表示他所有的 obervers 沒有一個狀態(tài)處理 STARTED 或者 RESUMED绘迁,注意合溺,這不代表沒有 observers。
@Override
protected void onInactive() {
super.onInactive();
}
}
關(guān)于自定義LiveData缀台,主要是重寫這幾個方法棠赛,當LiveData處于活躍狀態(tài),可以調(diào)用onActive()
方法膛腐,當沒有任何觀察對象的時候睛约,就是調(diào)用onActive()
方法,observeForever()
的區(qū)別就是在onPause哲身、onStop辩涝、onDestroy的時候也會調(diào)用observe()
的onChange()
方法。