ViewModel 基本紀錄(Android Architecture Component)

Overview


ViewModel 為 Android Architecture Component 其中一部分,主要的用途為以生命週期方式來儲存與管理UI相關數據。好處為當配置更改(螢幕旋轉)之後能夠予許數據繼續存在

以架構來說通常是作為 MVVM 的 VM(ViewModel) 角色來呈現, 透過把和 View 不相關的邏輯提取出來放到 VM,一方面可以減輕 View 的職責,一方面提高其它模組內聚力,也讓測試更容易撰寫。

Dependency


參考官網

實作 ViewModel


實作方式非常簡單,只要繼承 ViewModel 即可。通常 ViewModel 會和 LiveData 同時使用關於 LiveDate 請參考這裡
如同 Overview 提到的 ViewModel 可以在配置改變時自動保留數據,因此應該盡量把數據部分放到 ViewModel 而不是 Actvity 或 Fragment
public class MyViewModel extends ViewModel {  

private static final String TAG = MyViewModel.class.getSimpleName();

}

Note:通常會和 LiveData一起使用,但這裡為了方便說明,先不加入LiveData。

Using in Activity


public class ViewModelMainActivity extends AppCompatActivity {  

private static final String TAG = ViewModelMainActivity.class.getSimpleName();

private MyViewModel mViewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_model_main_activity);

mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
Log.d(TAG,"mViewModel.toString():"+ mViewModel.toString());
}
}

第12行透過 ViewModelProviders.of(this).get(MyViewModel.class); 初始化 mViewModel。
第13行用來測試旋轉螢幕後是否為同一個 ViewModel 實體。接著你可以開始旋轉螢幕了。
Note :
1.注意在 ViewModel 內絕不可引用 View, Lifecycle, 或是任何本身還會引用 activity context 的類別若 ViewModel 內需要使用 context 就繼承 AndroidViewModel
2.當呼叫 ViewModelProviders.of(this).get(MyViewModel.class); 之後,ViewModel 就會保存在記憶體中,直到它的作用域消失。也就是當ViewModelMainActivity 為 finish 狀態時,ViewModel 即會消失。

LiveDate 和 ViewModel 共用


LiveData 的用途為提供 observer 可以觀察本身所擁有的數據,而 ViewModel 則是提供 View 數據並可自動處理配置變化所引發的事件。
這 2 者共同使用對於 View 來說便可發揮極大的功效。
public class MyViewModel extends ViewModel {  

private static final String TAG = MyViewModel.class.getSimpleName();

private MutableLiveData<List<User>> mUsers;

public LiveData<List<User>> getUsers() {
if (mUsers == null) {
mUsers = new MutableLiveData<>();
loadUsers();
}
return mUsers;
}

private void loadUsers() {
...
}
}

 

Scope of ViewModel


從圖中可以看到當 Activity 在 onCreate 時,ViewModel 就跟著產生。而當 Activity finish 之後,呼叫完 onDestroy 方法後,ViewModel 就跟著消失。

在 Fragment 之間分享數據


若同一個 Activity 擁有 2 個 fragment , 也可以使用 ViewModel 讓這 2 個 fragment 共享數據。
public class SharedViewModel extends ViewModel {  
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

public void select(Item item) {
selected.setValue(item);
}

public LiveData<Item> getSelected() {
return selected;
}
}

public class MasterFragment extends Fragment {  

private SharedViewModel model;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}

public class DetailFragment extends Fragment {  

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

model.getSelected().observe(this, { item ->
// Update the UI.
});
}
}

注意這 2 個 fragment 都使用了 getActivity 來取得 ViewModelProvider,因此,這 2 個 fragment 都接受相同的 SharedViewModel 實體。

這個做法有以下優點
1. Activity 不需要做任何事,也不需要了解 Fragment 之間的溝通。
2. Fragment 不需要彼此了解。若其中一個 Fragment 發生問題,另一個 Fragment 繼續正常工作。

 

 

 

 

 

 

 

Orignal From: ViewModel 基本紀錄(Android Architecture Component)

0 意見:

張貼留言

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Affiliate Network Reviews