-
簡單demo
效果:點(diǎn)擊按鈕,數(shù)字加一
控件:一個(gè)TestView城菊,一個(gè)Button。
-
具體實(shí)現(xiàn)
activity_main.xml
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_weight="1"
android:textColor="#000000"
android:gravity="center"
android:textSize="50dp"/>
<Button
android:id="@+id/button"
android:layout_width="1px"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="+1"
android:textSize="50dp"
android:textColor="#000000"/>
MyViewModel (這里只定義一個(gè)簡單的變量number)
public class MyViewModel extends ViewModel {
public int number = 0;
}
MainActivity
public class MainActivity extends FragmentActivity{
private MyViewModel myViewModel;
private TextView textView;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
myViewModel = new ViewModelProvider(this,new ViewModelProvider.NewInstanceFactory()).get(MyViewModel.class); //綁定ViewModel
textView = findViewById(R.id.textview);
textView.setText(String.valueOf(myViewModel.number));// Activity重新創(chuàng)建時(shí)保存number值
button = findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myViewModel.number++;
textView.setText(String.valueOf(myViewModel.number));
}
});
}
}
-
詳細(xì)介紹
1. ViewModel的生命周期
上圖是官網(wǎng)給的生命周期圖,我們可以知道ViewModel存在于Activity各種生命周期盗忱。這樣我們就不用擔(dān)心Activity被destory、重新create時(shí)羊赵、或者旋轉(zhuǎn)時(shí)趟佃,數(shù)據(jù)被銷毀。比如上面的demo昧捷,旋轉(zhuǎn)屏幕時(shí)闲昭,ViewModel不會(huì)重新創(chuàng)建,我們可以直接獲取number的值靡挥。
2.優(yōu)化使用(在Fragment之間共享數(shù)據(jù))
Activity中兩個(gè)或多個(gè)Fragment之間需要通信是很常見的序矩。這些Fragment可以使用同一個(gè)Activity作用范圍下的ViewModel來處理通信。
public class TestViewModel extends ViewModel {
private final MutableLiveData<String> data = new MutableLiveData<>();
public void setData(String s){
data.setValue(s);
}
public MutableLiveData<String> getData(){
return data;
}
}
public class AFragment extends Fragment {
private TestViewModel model;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a, null);
model = new ViewModelProvider(getActivity(),new ViewModelProvider.NewInstanceFactory()).get(TestViewModel.class);
model.setData("a");
return v;
}
}
public class BFragment extends Fragment {
private TestViewModel model;
private TextView textView;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_b, null);
textView = v.findViewById(R.id.txt_b);
model = new ViewModelProvider(getActivity(),new ViewModelProvider.NewInstanceFactory()).get(TestViewModel.class);
model.getData().observe(getActivity(), new Observer<String>() {
@Override
public void onChanged(String s) {
textView.setText(s);
}
});
return v;
}
}
注意這兩個(gè)Fragment在使用ViewModelProvider獲取ViewModel時(shí)是用的getActivity()跋破。因此簸淀,這兩個(gè)Fragment都會(huì)收到相同的TestViewModel 實(shí)例瓶蝴,這個(gè)實(shí)例作用域是Activity。
這種方法提供了以下好處:
這個(gè)Activity不需要做任何事情租幕,也不需要了解有關(guān)此通信的任何信息舷手;
Fragment之間不需要了解彼此,除了TestViewModel 的聯(lián)系劲绪。如果一個(gè)fragment消失了男窟,其他fragment還可以繼續(xù)正常工作;每個(gè)Fragment都有其自己的生命周期贾富,并且不受其他生命周期的影響歉眷。如果一個(gè)Fragment替換另一個(gè)Fragment,UI將繼續(xù)工作而不會(huì)出現(xiàn)任何問題颤枪。