一、什么是ViewModel
之前有篇文章已经介绍过dataBinding,dataBinding使用。这里来学习一下ViewModel。
概念
- 让数据与UI隔离: 让ViewModel来获取数据加工数据并且回调给UI层。相当于MVP中的P层。
- 数据与生命周期绑定: ViewModel与注册的Activity的生命周期绑定,有着与Activity同步的生命周期。界面销毁会调用ViewModel的onCleared()方法。
- 数据持久化: ViewModel不会因为屏幕的旋转导致Activity重新创建而重置数据(这样避免了Activity被旋转数据丢失的问题)。
- Activity相互独立: ViewModel的数据是独立的,它跟每一个绑定的Activity都是实例一个单独的数据(意思是它无法跟多个Activity绑定后同步共享数据)。
- 完美配合Fragment: ViewModel可以与一个Activity与多个Fragment绑定后共享数据(你终于可以不用很蛋疼的把Fragment的数据暂存到Activity里了),并且可以都与他们的生命周期关联,这样Fragment短暂的生命周期将不在让你烦恼数据的暂存问题。
二、简单使用
自定义ViewModel:
public class MyViewModel extends ViewModel {
public MutableLiveData<String> userName = new MutableLiveData<>();
@Override
protected void onCleared() {
super.onCleared();
Log.e("MyViewModel>>>>>>>","onCleared");
}
}
xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="vm"
type="com.xinyartech.viewModel.MyViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{vm.userName}" />
</RelativeLayout>
</layout>
activity源码:
public class MyViewModelActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ActivityViewModelBinding binding = DataBindingUtil.setContentView(this,
R.layout.activity_view_model);
ViewModelProvider viewModelProvider = new ViewModelProvider(this);
final MyViewModel viewModel = viewModelProvider.get(MyViewModel.class);
//观察vm层数据变化
viewModel.userName.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.e("ViewModel数据发生变化了", s);
binding.tv.setText(s);
}
});
//v层绑定vm层
binding.setVm(viewModel);
//模拟数据
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
viewModel.userName.setValue("数据来了");
}
}, 5000);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e("MyViewModelActivity>>>>","activity销毁");
}
}
使用ViewModelProvider方式为ViewModel创建一个单例。
效果:
- 隔5s钟,修改viewModel中的数据,在onChanged方法中监听到数据并更新UI。
- 返回键退出当前界面,回调viewModel的onCleared()方法。这就说明了它是具有感知activity的能力。