Android进阶之MVVM+DataBinding框架模式(更新中)

Posted 彬sir哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android进阶之MVVM+DataBinding框架模式(更新中)相关的知识,希望对你有一定的参考价值。

MVVM框架

MVVM架构简介
C#很早就有了MVVM的开发模式,android手机中的MVVM一直到去年Google的I\\O大会上才推出,姗姗不迟。MVVM这中开发模式的优点自不必多说,可以实现视图和逻辑代码的解耦,而且,按照Google的说法,使用了MVVM的开发模式,还可以提高布局文件的解析速度,个人觉得这一点非常重要。我们在安卓开发中经常需要写很多个findViewById,让人心烦,很多人不想写帝个于是用了一些注解框架,可是注解框架无论性能多好,效率总是要低于findViewById的,因此,Android中的MVVM也即databinding可以帮助我们彻底解决这个问题

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来导入需要用的包-->
        <import type="android.view.View" />
         <!--使用关键字variable来声明一个变量,name为变量名,type为指向的对象,可以是类名也可以是类名的别名-->
        <variable
            name="userViewModel"
            type="com.mvvm.model.mvvm.viewmodel.MVVMDataViewModel" />

        <variable
            name="handlers"
            type="com.mvvm.model.mvvm.view.MVVMActivity" />
        <!--对于基本类型,可以像java代码一样不用去导入包,直接使用-->
        <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注释
     * @return
     */
    @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:

/**
 * View层
 */
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层:
用来进行具体的数据请求操作

/**
 * 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

以上是关于Android进阶之MVVM+DataBinding框架模式(更新中)的主要内容,如果未能解决你的问题,请参考以下文章

Android安卓进阶技巧之Kotlin结合Jetpack构建MVVM

Android进阶笔记14:RoboBinding(实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架)

Android kotlin 系列讲解(进阶篇)高级项目架构模式 - MVVM

MVVM 进阶版:MVI 架构了解一下~

《Android构建MVVM》系列 之 MVVM架构快速入门

Android基础——框架模式MVVM之DataBinding的实践