MVVM框架 MVVM框架实现了数据和视图的绑定(DataBinding),当数据变化时,视图会自动更新;反之,当视图变化时,数据会自动是新 MVVM模式与MVP模式一样,也将应用分为三层,并且各个对应的层的职责相似:
- Model层,主要负责数据的提供。Model层提供业务逻辑的数据结构(比如,实体类),提供数据的获取(比如,从本地数据库或者远程网络获取数据),提供数据的存储
- View层,主要负责界面的显示。View层不涉及任何的业务逻辑处理,它持有ViewModel层的引用,当需要进行业务逻辑处理时通知ViewModel层
- ViewModel层,主要负责业务逻辑的处理。ViewModel层不涉及任何的视图操作。通过官方提供的Data Binding库,View层和ViewModel层中的数据可以实现绑定,ViewModel层中数据的变化可以自动通知View层进行更新,因此ViewModel层不需要持有View层的引用。ViewModel层可以看作是View层的数据模型和Presenter层的结合
MVVM模式与MVP模式最大的区别在于:ViewModel层不持有View层的引用。这样进一步降低了耦合,View层代码的改变不会影响ViewModel层
MVVM模式相对于MVP模式主要有如下优点:
- 进一步降低了耦合。ViewModel层不持有View层的引用,当View层发生改变时,只要View层绑定的数据不变,那么ViewModel层就不需要改变。而在MVP模式下,当View层发生改变时,操作视图的接口就要进行相应的改变,那么Presenter层就需要修改了
- 不用再编写很多样板代码。通过官方的Data Binding库,UI和数据之间可以实现绑定,不用再编写大量的findViewById()和操作视图的代码了。总之,Activity/Fragment的代码可以做到相当简洁
一、DataBinding使用步骤:
- 启用DataBinding
- 修改布局文件为DataBinding布局
- 数据绑定
二、使用MVVM框架步骤:
- 提供View、ViewModel以及Model三层
- 将布局修改为DataBinding布局
- View与ViewModel之间通过DataBinding进行通信
- 获取数据并展示在界面上
MVVM的全称是Model(模型)–View(视图)–ViewModel(视图模型):
MVVM可以算是MVP的升级版,将Presenter改为了VIewModel。关键在于View和Model的双向绑定,当View有用户输入后,ViewModel通知Model更新数据,同理Model数据更新后,ViewModel通知View更新
MVVM的优势如下: 1、View和Model双向绑定,一方的改变都会影响一方,开发者不用再去手动修改UI的数据 2、不需要findViewById也不需要butterknife,不需要拿到具体的View去设置数据绑定监听器等等,这些都可以用DataBinding完成 3、View和Model的双向绑定是支持生命周期检测的,不会担心页面销毁了还有回调发生,这个由lifeCycle完成 4、不会像MVC一样导致Activity中代码量巨大,也不会像MVP一样出现大量的View和Presenter接口。项目结构更加低耦合
什么是databinding
DataBinding是谷歌官方发布的一个框架,顾名思义即为数据绑定,是MVVM模式在Android上的一种实现,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰
接下来进入正题 首先要启用databinding: 启用DataBinding的方法是在对应Model的build.gradle文件里加入以下代码,同步后就能引入对DataBinding的支持
android {
...
dataBinding {
enabled = true
}
}
下面具体介绍下MVVM框架: 1、VM层: 这里根据MVVMActivity的布局文件activity_mvvmpattern,介绍下Data Binding:
Data Binding对使用的环境还是有一定要求的:Android Studio版本在1.3以上,gradle的版本要在1.5.0-alpha1以上。 需要在Android SDK manager中下载Android Support repository
然后在对应的Module的build.gradle中添加:
android {
....
dataBinding {
enabled =true
}
}
然后使用databinding语法对xml进行数据绑定,我们将Click事件、输出结果都绑定到VM上
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="userViewModel"
type="com.mvvm.model.mvvm.viewmodel.MVVMDataViewModel" />
<variable
name="handlers"
type="com.mvvm.model.mvvm.view.MVVMActivity" />
<variable
name="data"
type="String" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="@+id/btnMVVM"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{handlers.onClickLoadData}"
android:text="点击请求数据" />
<Button
android:id="@+id/btnToast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{handlers.onClickShowToastName}"
android:text="点击请求数据并Toast提示" />
<TextView
android:id="@+id/tvData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@{userViewModel.data}" />
</LinearLayout>
</layout>
在data中定义的variable(变量)节点,name属性表示变量的名称,type表示这个变量的类型,实例就是我们实体类的位置,当然,这里你也可以换这种方式:
<data>
<import type="android.view.View" />
<variable
name="userViewModel"
type="com.mvvm.model.mvvm.viewmodel.MVVMDataViewModel" />
</data>
BaseObservable,observable:观察者 还是MVVMDataViewModel类来举例,BaseObservable提供了两个刷新UI的方法,分别是notifyPropertyChanged() 和 notifyChange() ???1.notifyPropertyChanged();只会刷新属于它的UI,就如代码,他只会更新name ???2.notifyChange();会刷新所有UI
Bean类继承BaseObservable notifyPropertyChanged()需要传入一个int类型的参数,这个参数就是int fieldId,指的就是那个形参name
Bindable用于将数据绑定到视图 VM层具体类:这里注意具体的属性需要加@Bindable,否则绑定无效
public class MVVMDataViewModel extends BaseObservable implements MVVMLoadDataCallback{
private MVVMDataModel model;
public MVVMDataViewModel() {
model = new MVVMDataModel();
}
@Bindable
public String getData() {
return model.mData;
}
public void loadUserData() {
model.requestData(this);
}
@Override
public void onSuccess() {
notifyPropertyChanged(com.mvvm.model.BR.data);
}
@Override
public void onFailure() {
}
}
选择你自己工程下的BR或者第三个BR 2、View层(MVVMActivity) 引入VM:
public class MVVMActivity extends AppCompatActivity {
private MVVMDataViewModel userViewModel;
private TextView tvData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMvvmpatternBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_mvvmpattern);
userViewModel = new MVVMDataViewModel();
binding.setUserViewModel(userViewModel);
binding.setHandlers(this);
tvData = binding.tvData;
}
public void onClickShowToastName(View view) {
Toast.makeText(this, tvData.getText().toString(), Toast.LENGTH_LONG).show();
}
public void onClickLoadData(View view) {
userViewModel.loadUserData();
}
}
3、Model层: 用来进行具体的数据请求操作
public class MVVMDataModel {
public String mData;
public MVVMDataModel() {
this.mData = "初始数据";
}
public void requestData(MVVMLoadDataCallback callback) {
this.mData = "数据请求成功";
callback.onSuccess();
}
}
MVVM虽然有这些个优点,但使用起来的坑也是不少的,所以日前MVVM框架在实际开发中应用并不是很多,主要以MVP框架开发为主
最后提供下github源码,供大家参考:testMVVM
|