MVC:M-Model-模型、V-View-视图(xml)、C-Controller-控制器(activity),MVP作为MVC的演化版本,M-Model-模型、V-View-视图(activity)、P-Presenter-表示器。 从MVC和MVP两者结合来看,Controlller/Presenter在MVC/MVP中都起着逻辑控制处理的角色,起着控制各业务流程的作用。而 MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控 View与Model之间的间接交互,
1.MVVM模式分为Model,View,ViewModel 三个部分
View View:界面层,对应于Activity,XML,View,负责数据显示以及用户交互。View还包括ViewDataBinding,
ViewModel ViewModel:关联层,将Model和View进行绑定,持有view 和 model,负责业务逻辑处理。Model或者View更改时,实时刷新对方。。
Model Model:数据层,包含数据实体和对数据实体的操作。
Binder绑定器 Android中的数据绑定技术由DataBinding和LiveData共同实现。当Activity/Fragment接收到来自ViewModel中的新数据时(由LiveData自动通知数据的改变),将这些数据通过DataBinding绑定到ViewDataBinding中,UI将会自动刷新。
MVVM的优势
1),使得M,V,VM的解耦更加彻底,在mvp模式中,p需要持有V的引用,才能去刷新UI,在MVVM模式中,View和Model使用databingding进行双向绑定,一方改变会直接通知另外一方,使得viewModel能专注于业务逻辑的处理,而不需要去关心UI刷新。 2),不会像MVC一样导致Activity中代码量巨大,也不会像MVP一样出现大量的View接口(Presente与View是通过接口进行交互的)。项目结构更加低耦合。
MVVM的劣势
1),数据绑定使得Bug很难被调试。 2),一个大的模块中,model也会很大,虽然使用方便了也很容易保证了数据的一致性,但是长期持有,不释放内存,就造成了花费更多的内存。 3),数据双向绑定不利于代码重用。客户端开发最常用的重用时View,但是数据双向绑定技术,让你在一个View都绑定了一个model,不同模块的model都不同,那就不能简单重用View了
总结
1.MVVM并不会提升程序的性能,甚至如果用不好还会降低性能。
2.MVVM会增大代码的总量。
3.阅读MVVM的代码你必须不停的跳来跳去,跳到你恶心想吐。
4.MVVM将让你的程序完全解耦。
Databinding框架
Databinding和MVVM的关系
MVVM是一种架构模式,DataBinding是一个实现数据和UI绑定的框架,是实现MVVM模式的工具。
引入DataBinding 在App的build.gradle添加
android{
.....
dataBinding {
enabled = true
}
}
固定写法
* 最外层用<layout>标签嵌套,注意layout的首字母是小写的“l”
* <layout>标签的下面紧跟着一个<data>标签,这个标签其实就是让我们进行数据绑定的一个标签
* <data>标签中,属性class databingView 名称包含着<variable>标签,这个标签就是我们将“变量”
放置的位置
* <variable>标签里面分别有<type> <name>两个标签,分别来标识变量类型和变量名称
* <type>标签 标识变量类型,比如java.lang.String这就是String类型,
com.guaju.mvvm.bean.User 这个就是一个我自定义的一个User类型
* <name>标签 表示的就是我们定义的一个变量名称,这个变量名称我们会在下方的布局和对应的java代码中引用到
使用。 建立数据模式
public class Author extends BaseObservable {
private String name;
private Date birthdate;
private boolean male;
@Bindable
public String getName() {return name;}
public void setName(String name) {this.name = name;}
@Bindable
public Date getBirthdate() {return birthdate;}
public void setBirthdate(Date birthdate) {this.birthdate = birthdate;}
@Bindable
public boolean isMale() { return male;}
public void setMale(boolean male) {this.male = male;}
- 新建一activity的布局文件,在layout节点中添加data定义,Rebuild Project,框架将自动生成AuthorBinding类,
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class="AuthorBinding">
<variable name="vMode" type="cn.com.ssii.mvvm.book.viewmodel.AuthorViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{vMode.author.name}" />
</LinearLayout>
</layout> - 新建AuthorViewModel,并在xml文件中设置属性绑定
AuthorViewModel
public class AuthorViewModel {
private Activity activity;
private ViewDataBinding binding;
public Author author;
public AuthorViewModel(Activity activity, ViewDataBinding binding) {
author = new Author();
author.setBirthdate(new Date());
author.setMale(true);
author.setName("Jim");
this.activity = activity;
this.binding = binding;
this.binding.setVariable(BR.vMode,this);
}
} 水电费水电费 -
activity: public class AuthorActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewDataBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_author);
AuthorViewModel viewModel = new AuthorViewModel(this, binding);
}
} 事件绑定 在使用mvvm后,不用在Activity中去findview,然后设置各的事件了,可能把事件定义到ViewMode或其它类中,在xml文件中定义对应变量并给事件绑定处理方法即可,如: xml: ? <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{vMode.buttonClick}" />
viewmodel:
public void buttonClick(View view) {
Toast.makeText(activity, "你点了我一下", Toast.LENGTH_SHORT).show();
}
参数必须是View ,参数要对应于setOnClickListener(onClickListener listener) 对应的onClickListener 要实现的接口,即public void onClick(View) 。其他的方法也一样
?
|