上一回仅仅是初次使用EventBus与LiveData,个人感觉EventBus并不适合自己,LiveData才是自己想要的,但是,LiveData的通知管理很蛋疼,所以自己使用了多个LiveData实例,当时感觉美滋滋的。最近,感觉很不爽,就这么几个实例,开始寻找执行轨迹的时候,已经很麻烦了,难道以后还要继续增加实例,不可能,程序员的奥义,完全重复的方法体,有且只有一个就可以了。so,我又想到了一个好办法。
本次依然不讲源码,那不是我的实力允许的,这里只讲思路以及自己的具体代码
一、创建ViewModel
这个是LiveData传递数据的基础,直接来吧
public class MyLiveDataViewModel implements Serializable {
public static final long serialVersionUID = 38L;
/**
* 无事发生
*/
public static final int DEFAULT = -1;
public static final int userList = 1000; (对应flag)//客户列表
public static final int userListFresh = 10001;(对应type)
public static final int userListFresh2 = 10002;(对应type)
/**
* 初始化
*
* @param flag 标记,类似信道,
* @param type 操作方法标记
* @param object 传值(ps:如果没有固定的类,可用Bundle来当这个Object)
*/
public MyLiveDataViewModel(int flag, int type, Object object) {
this.map = new HashMap<>();
map.put(flag, type);
map.put(type, object);
}
private Map<Integer, Object> map;
public Map<Integer, Object> getMap() {
if (map == null) {
map = new HashMap<>();
}
return map;
}
private void setMap(Map<Integer, Object> map) {
this.map = map;
}
//给实例化后的viewModel进行赋值
public void putData(int flag, int type, Object object) {
getMap().put(flag, type);
getMap().put(type, object);
}
//自定义已读消息,将flag标记对应的value设为DEFAULT
public void clean(int flag) {
map.put(flag, DEFAULT);
}
//获取flag对应的value(对应type),如果无值或者被标记为DEFAULT,表示消息已读或者无消息
public Integer getType(int flag) {
if (map != null) {
if (map.get(flag) == null) {
return DEFAULT;
}
return (Integer) map.get(flag);
}
return DEFAULT;
}
//获取type对应的value(对应Object)
public Object getObject(int type) {
if (map != null) {
return map.get(type);
}
return null;
}
//打印已保存的消息数据
public void showLog() {
if (map != null) {
StringBuilder builder = new StringBuilder();
builder.append("{");
for (int key : map.keySet()) {
builder.append(key)
.append(":")
.append(map.get(key))
.append(",");
}
builder.append("}");
MyLog.e("MyLiveDataViewModel", "已保存的值 = " + builder);
} else {
MyLog.e("MyLiveDataViewModel", "空值");
}
}
}
代码自己看吧,都开始用LiveData了,就默认都会了。
1)这里的Serializable没什么用,以前使用intent传递数据,序列化用的,复制的时候就继续用了。(ps:以后的新项目应该可以只使用LiveData传递数据,个人认为简单方便)
2)该类仅使用一个map作为变量,从初始化方法可以看出,是连续的数据存储,上方的static数据与其对应
3)DEFAULT变量,这个是自定义的消息阻断标记,后面使用的时候可以看到用法,很好理解
二、初始化ViewModel
private static MutableLiveData<MyLiveDataViewModel> liveData = new MutableLiveData<>();
public static void putValue(int flag, int type, Object object) {
MyLiveDataViewModel model = MyApplication.getLiveData().getValue();
if (model == null) {
model = new MyLiveDataViewModel(MyLiveDataViewModel.DEFAULT, MyLiveDataViewModel.DEFAULT, null);
}
model.putData(flag, type, object);
getLiveData().postValue(model);
}
public static MutableLiveData<MyLiveDataViewModel> getLiveData() {
if (liveData == null) {
liveData = new MutableLiveData<>();
}
return liveData;
}
从代码里可以看出,数据都是复用,有个一个好处,就是假设出现了需要同时传递多个数据的情况时,数据不会被覆盖。
三、如何使用
1)如何传值
//MyApplication.putValue(int flag, int type, Object object)
//flag(标记,用户列表),type(类型,刷新列表),object(传值,这里不需要传值)
MyApplication.putValue(MyLiveDataViewModel.userList, MyLiveDataViewModel.userListFresh, null);
User user = new User();
//flag(标记,用户列表),type(类型,执行另外的刷新策略),object(传值,假设这里需要传一个用户,自行替换就行)
MyApplication.putValue(MyLiveDataViewModel.userList, MyLiveDataViewModel.userListFresh2, user);
2)如何接收数据
//该方法需在onCreate里执行
private void initLiveData() {
MyApplication.getLiveData().observe(this, new Observer<MyLiveDataViewModel>() {
@Override
public void onChanged(@Nullable MyLiveDataViewModel viewModel) {
if (viewModel != null && viewModel.getType(MyLiveDataViewModel.userList) == MyLiveDataViewModel.userListFresh) {
//执行列表刷新
//viewModel的clean方法,将map中flag对应的value修改为DEFAULT,标记为已使用
viewModel.clean(MyLiveDataViewModel.userList);
//将已使用的数据重新填充回LiveData,此时observe会再次被触发,
//但是已被标记为DEFAULT,无事件处理,完成了一次数据传递,
//并且其他的消息并未受到影响
MyApplication.getLiveData().postValue(viewModel);
freshList();
}else if(viewModel != null && viewModel.getType(MyLiveDataViewModel.userList) == MyLiveDataViewModel.userListFresh2){
//执行另外的刷新策略
//需要传递Object值时
freshData((User)viewModel.getObject());
viewModel.clean(MyLiveDataViewModel.userList);
MyApplication.getLiveData().postValue(viewModel);
}
}
});
}
以上,就是个人最新的LiveData使用,如果大家有更棒的想法,多多分享。