MVVM 概述
谈谈对MVVM的看法
说到MVVM,不得不提MVC、MVP,前面的那对CP,在某些角度或理解上,倒挺符合他们CP的气质,毕竟他们真的太相似了,写完这三篇文章之后,会专门说说开发的时候该如何去选用这些框架。
言归正传,MVVM新引入了VM的概念,也就是ViewModel,用的时候可以继承ViewModel或者AndroidViewModel,谈到这里,不禁要想,这才是google的亲儿子吗,试问,用MVC的时候Android提供了Controller吗?MVP时android提供了Presenter吗?写到这里的时候,小编马上就去搜索了下,还真有Presenter,我是瑟瑟发抖,真准备求android 粑粑原谅,看了看源码,不禁把肾放回了腰间。androidx.leanback.widget.Presenter 源码有点长就不贴了,先看看示例
public class StringTextViewPresenter extends Presenter {
// This class does not need a custom ViewHolder, since it does not use
// a complex layout.
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
return new ViewHolder(new TextView(parent.getContext()));
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, Object item) {
String str = (String) item;
TextView textView = (TextView) viewHolder.mView;
textView.setText(item);
}
@Override
public void onUnbindViewHolder(ViewHolder viewHolder) {
// Nothing to unbind for TextView, but if this viewHolder had
// allocated bitmaps, they can be released here.
}
}
从例子上看,类似于在Adapter中的做法,虽然如此也能实现MVP的效果,并且这种做法会使View变得更干净,但是这个时候除了xml,还有V的存在吗?貌似这是最理想的状态,氮素啊,这不又回到了Activity的状态了。所以,我姑且就觉得这不是为MVP准备的。
更何况还有DataBinding,MVVM简直如有神助。
Model–View–ViewModel (MVVM) 是一个软件架构设计模式
MVC:(View-Model-Controller)
将View、Model、Controller代码块进行划分,使得程序大部分分离,降低耦合。这个模块,后续会出一个专门的文章,之所以放在最后,文章中会提到。
【MVP:(VIew-Model-Presenter)
Presenter整个功能的服务者,当用户通过界面(View)与应用进行交互或潜在交互时,界面将有效事件上报给Presenter,Presenter则根据事件需求进行处理,包括与数据(Model)之间的交互。形象来说就是:MVP就是一个非自助式餐厅,顾客就相当于我们的用户,餐厅本身相当于View,餐厅工作人员相当于Presenter,餐厅的食材相当于Model。用户与View进行交互时,相当于客户来到餐厅,此时会触发工作人员进行服务,有点餐操作时,Presenter获取Model数据,并呈现给用户。
MVVM:(Model–View–ViewModel)
MVVM可以算是MVP的升级版,将Presenter改名为ViewModel。关键在于View和Model的双向绑定,当View有用户输入后,ViewModel通知Model更新数据,同理Model数据更新后,ViewModel通知View更新。
MVVM 使用到的库
1、Android官方架构组件Lifecycle
2、Android官方架构组件ViewModel
3、Android官方架构组件LiveData
4、Android官方架构组件Paging
5、Android官方架构组件Navigation
6、Android官方架构组件Data
7、Android-common
8、Android-common-mvvm
MVVM 实现
定义基类
1、BaseVActivity
package com.ww7h.common.mvvm.v;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import com.ww7h.ww.common.bases.activity.BaseActivity;
/**
* ================================================
* 描述:
* 来源: Android Studio.
* 项目名: Android-common-mvvm
* 包名: com.ww7h.common.mvvm.v
* 创建时间: 2019/4/5 18:54
*
* @author ww Github地址:https://github.com/ww7hcom
* ================================================
*/
public abstract class BaseVActivity<T extends BaseActivity<T>, B extends ViewDataBinding> extends BaseActivity<T> {
protected B vdBinding;
@Override
protected boolean getDesignPattern() {
return true;
}
@Override
protected void initContentView() {
super.initContentView();
vdBinding = DataBindingUtil.setContentView(this, getContentView());
}
}
2、BaseVFragment
package com.ww7h.common.mvvm.v;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.ww7h.ww.common.bases.fragment.BaseFragment;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* ================================================
* 描述:
* 来源: Android Studio.
* 项目名: Android-common-mvvm
* 包名: com.ww7h.common.mvvm.v
* 创建时间: 2019/4/5 18:57
*
* @author ww Github地址:https://github.com/ww7hcom
* ================================================
*/
public abstract class BaseVFragment<T extends BaseFragment<T>, B extends ViewDataBinding> extends BaseFragment<T> {
/**
* 当前视图绑定的对象
*/
protected B vdBinding;
@Nullable
@Override
protected View getContentView(@NotNull LayoutInflater inflater, @Nullable ViewGroup container) {
vdBinding = DataBindingUtil.inflate(inflater, getResourceId() ,container , false);
return vdBinding.getRoot();
}
@Override
protected boolean getDesignPattern() {
return true;
}
}
调用Demo
1、定义layout文件,主要差别,root标签,数据绑定使用标签,标签用来绑定数据,@{}数据使用
<?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