ViewModel和LiveData存储数据和传递数据
学习地址:
ViewModel Overview | Android Developers
https://developer.android.google.cn/topic/libraries/architecture/viewmodel
demo下载:
viewModel,liveData,lifecycle的简单使用demo-CSDN下载
https://download.csdn.net/download/baidu_31093133/10586939
开发中可能会遇到下面的问题:
1、当activity旋转屏幕的时候,我们需要重新加载数据
2、fragment之间传递数据
而使用viewModel可以很方便的解决这些问题,因为Activity重复创建的时候,持有的是同一个viewModel实例
viewModel使用:
1、创建一个类继承viewModel
2、使用liveData存储数据
3、在需要的地方接受数据变化
4、数据变化的时候在需要的地方设置新数据
下面是代码示例:
NameViewModel:
/**
* Created by HONGDA on 2018/8/6.
* A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.
* viewModel不可持有view的引用或者任何持有activity上下文的类的引用
* 如果需要Application的context的话可以继承AndroidViewModel
* Activity重复创建的时候,持有的是同一个viewModel实例
*/
public class NameViewModel extends ViewModel {
//liveData通常和viewModel一起使用
private MutableLiveData<String> mCurrentName;
public MutableLiveData<String> getmCurrentName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData<String>();
}
return mCurrentName;
}
//如果需要可以在这里释放资源
@Override
protected void onCleared() {
super.onCleared();
}
在activity里使用viewModel:
//是ViewModelProviders而不是ViewModelProvider
//1、获取ViewModel
nameViewModel = ViewModelProviders.of(this).get(NameViewModel::class.java)//传入自定义viewModel的类
//2、创建观察者
var nameObserver: Observer<String> = Observer<String> { t -> tvName.text = t ?: "不知道" }
//3、观察liveData的变化
nameViewModel.getmCurrentName().observe(this, nameObserver)
当数据变化的时候,改变textview的值
效果图:hello world!是初始值,然后点击另外两个按钮使用viewModel传递不同的值
Fragment之间传值:
public class FragmentOne extends Fragment {
private EditText edContent;
private Button btnSend;
private NameViewModel model;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
edContent = view.findViewById(R.id.ed_content);
btnSend = view.findViewById(R.id.btn_send);
//获取viewModel
model = ViewModelProviders.of(getActivity()).get(NameViewModel.class);
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取到liveData后设置liveData的值
model.getmCurrentName().setValue(edContent.getText().toString());
}
});
return view;
}
}
public class FragmentTwo extends Fragment {
private TextView textName;
private NameViewModel model;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_two, container, false);
textName = view.findViewById(R.id.tv_fragment2_name);
//获取viewModel
model = ViewModelProviders.of(getActivity()).get(NameViewModel.class);
//监听值的变化
model.getmCurrentName().observe(getActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
if (TextUtils.isEmpty(s)) s = "哦,是个null";
textName.setText(s);
}
});
return view;
}
}
注意,这两个fragment都在同一个activity里,ViewModelProviders.of(getActivity()),这样获取到的就是同一个viewModel,也就可以传递或保存同一份数据了
效果图:横竖屏转换,数据也不会丢失,也不需要自己手动加载数据,viewModel会把数据保存在内存里直到activity销毁。
viewModel生命周期图:
上一篇: 用PHP实现WEB动态网页静态
下一篇: MYSQL日常使用命令整理_MySQL
推荐阅读
-
Android中Activity和Fragment传递数据的两种方式
-
MySQL数据库存储引擎和分支现状分析
-
在ASP.NET 2.0中操作数据之七十四:用Managed Code创建存储过程和用户自定义函数(下部分)
-
在ASP.NET 2.0中操作数据之七十三:用Managed Code创建存储过程和用户自定义函数(上部分)
-
springmvc和js前端的数据传递和接收方式(两种)
-
Android中Activity和Fragment传递数据的两种方式
-
mysql 海量数据的存储和访问解决方案
-
详解iOS App开发中session和coockie的用户数据存储处理
-
MySQL数据库存储引擎和分支现状分析
-
HTML5 Web存储方式的localStorage和sessionStorage进行数据本地存储案例应用