第一篇说了DataBinding,这回来shuoshuoMVVM的架构
其实databinding就是MVVM的一种工具,实现View和ViewModel的通信,在开发中我使用Activity和对应的一个viewmodel,acrivity负责初始化,ui操作,弹窗什么的东西,viewModel负责掌握数据,网络请求,逻辑操作,最终由viewModel承担了业务逻辑,而而驱动界面UI的变化,谷歌官方是怎么示范的呢,他们用的是LiveData这个类,比如在baseViewModel中:
/**
* UI变化LiveData,通知UI刷新
*/
public final class UIChangeLiveData extends SingleLiveEvent {
private SingleLiveEvent<String> showToastEvent;
private SingleLiveEvent<String> showLoadingEvent;
private SingleLiveEvent<Void> dismissLoadingEvent;
private SingleLiveEvent<Map<String, Object>> startActivityEvent;
private SingleLiveEvent<Map<String, Object>> startContainerActivityEvent;
private SingleLiveEvent<Void> finishEvent;
private SingleLiveEvent<Void> onBackPressedEvent;
public SingleLiveEvent<String> getShowToastEvent() {
return showToastEvent = createLiveData(showToastEvent);
}
public SingleLiveEvent<String> getShowLoadingEvent() {
return showLoadingEvent = createLiveData(showLoadingEvent);
}
public SingleLiveEvent<Void> getDismissLoadingEvent() {
return dismissLoadingEvent = createLiveData(dismissLoadingEvent);
}
public SingleLiveEvent<Map<String, Object>> getStartActivityEvent() {
return startActivityEvent = createLiveData(startActivityEvent);
}
public SingleLiveEvent<Map<String, Object>> getStartContainerActivityEvent() {
return startContainerActivityEvent = createLiveData(startContainerActivityEvent);
}
public SingleLiveEvent<Void> getFinishEvent() {
return finishEvent = createLiveData(finishEvent);
}
public SingleLiveEvent<Void> getOnBackPressedEvent() {
return onBackPressedEvent = createLiveData(onBackPressedEvent);
}
private <T> SingleLiveEvent<T> createLiveData(SingleLiveEvent<T> liveData) {
if (liveData == null) {
liveData = new SingleLiveEvent<>();
}
return liveData;
}
@Override
public void observe(LifecycleOwner owner, Observer observer) {
super.observe(owner, observer);
}
}
定义了许多事件,弹窗,loading,toast,返回按钮监听等,实现了通过变化数据去通知Activity刷新UI的操作,
又比如网络请求,在viewModel开始请求数据,得到数据,把这这个LiveData返回给activity,最后activity就能得到请求的数据
LoginActivity:
/**
* 登录按钮
*/
fun login(view: View) {
viewModel.login().observe(this, Observer {loginResult ->
//登陆成功
showToast(loginResult?.name)
})
}
loginViewModel:
/**
* 登录接口,只负责处理数据,不用管UI
*/
public MutableLiveData<LoginResponse> login(){
HashMap<String,Object> map = new HashMap();
map.put("phoneNo",phoneNo.get());
map.put("captcha",captcha.get());
final MutableLiveData<LoginResponse> data = new MutableLiveData<>();
Disposable disposable = RxHttp.postForm(Api.login)//接口名
.addEncoded("data", new Gson().toJson(map))//post数据
.asBaseResponse(LoginResponse.class)//回调数据类型
.compose(RxUtils.commonTransformer())//执行线程和失败重试
.compose(getLoadingTransformer())//loading弹窗
.subscribe((Consumer<LoginResponse>) response -> {
data.setValue(response);
msgLog.set("login成功 "+response.getName()+":"+response.getPhoneNo());
LoginUtil.saveLoginInfo(response);
LoginUtil.saveAuth(response.getAuth());
LoginUtil.saveLoginPhoneNo(response.getPhoneNo());
}, (Consumer<Throwable>)throwable ->
showToast(throwable.getMessage())
);
//添加到生命周期
addSubscribe(disposable);
return data;
}
这里的data是个LiveData,我们返回给activity这个liveData,当接口数据返回后,再设置data的值,这时候activity就能知道data的变化进行下一步操作。
不只是activity能使用,dialog等自定义布局的控件也可以使用,比如dialog使用方法就是:
mBinding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.dialog_select, null, false);
setContentView(mBinding.getRoot());
SelectDialogBean data = new SelectDialogBean();
mBinding.setData(data);
总结:databinding和liveData都是谷歌官方出的jetpack工具包中的内容,用起来比较方便,尤其是可以把原来的很多UI代码写在xml布局代码里面,极大提高开发UI的效率,从繁琐的UI代码中抽出身来关注业务逻辑,让xml不止是静态的布局文件,更能动态展示页面的变化。