Android开发MVVM设计模式的实现及ButterKnife兼容结合源码详解并总结优缺点

MVVM设计模式主要是view通过中间件viewModel与model数据模型交互,咱们可以看一下流程图:

本篇采用谷歌自带DataBinding 组件实现MVVM,只需要在app.gradle开启就行:

1dataBinding { 2 enabled = true 3}

View布局文件xml:

1<?xml version="1.0" encoding="utf-8"?> 2<layout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools"> 4 5 <data> 6 <import type="com.freddy.chat.MainViewModel"/> 7 <variable 8 name="viewModel" 9 type="MainViewModel" /> 10 </data> 11 12 <LinearLayout 13 android:layout_width="match_parent" 14 android:layout_height="match_parent" 15 android:orientation="vertical" 16 tools:context=".MainActivity"> 17 18 <Button 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:onClick="@{viewModel.getData}" 22 android:text="测试" /> 23 24 <TextView 25 android:id="@+id/tv_test" 26 android:layout_width="200dp" 27 android:layout_height="50dp" 28 android:layout_marginLeft="20dp" 29 android:text="@{viewModel.model.name}" /> 30 </LinearLayout> 31</layout>

View接口:

1package com.freddy.chat; 2 3/** 4 * Created by xie on 2020/10/15. 5 */ 6public interface MainView { 7 void moveText(int offset); 8}

View层Activity:

1public class MainActivity extends AppCompatActivity implements MainView { 2 private ActivityMainBinding binding; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 7 binding.setViewModel(new MainViewModel(this)); 8 9 } 10 @Override 11 public void moveText(int offset) { 12 binding.tvTest.setTranslationX(offset); 13 } 14}

业务层viewModel中间件:

1package com.freddy.chat; 2 3import android.view.View; 4 5/** 6 * Created by xie on 2020/10/14. 7 */ 8public class MainViewModel { 9 private String name = "测试"; 10 private MainModel model; 11 private MainView view; 12 13 14// @BindingAdapter("android:text") 15// public static void onTextChange(TextView view, CharSequence text) { 16// Log.e("tag", String.valueOf(text)); 17// } 18 19 20 public MainViewModel(MainView view) { 21 this.view = view; 22 this.model = new MainModel(); 23 model.setName(name); 24 } 25 26 public MainModel getModel() { 27 return model; 28 } 29 30 public void getData(View v) { 31 model.setName("MVVM测试"); 32 view.moveText(100); 33 } 34}

Model数据模型:

1package com.freddy.chat; 2 3package com.freddy.chat; 4 5import android.databinding.BaseObservable; 6import android.databinding.Bindable; 7 8import com.android.databinding.library.baseAdapters.BR; 9 10/** 11 * Created by xie on 2020/10/14. 12 */ 13public class MainModel extends BaseObservable { 14 private String name; 15 16 @Bindable 17 public String getName() { 18 return name; 19 } 20 21 public void setName(String name) { 22 this.name = name; 23 notifyPropertyChanged(BR.name);//刷新指定属性UI,刷新所有属性采用notifyChange(); 24 } 25}

兼容带ButterKnife老版本版本:

1protected abstract boolean isMvvM(); 2 3if (!isMvvM()) { 4 ButterKnife.bind(this); 5} 6 7protected View getContentView() { 8 View root = LayoutInflater.from(this).inflate(R.layout.activity_base, null); 9 FrameLayout content = (FrameLayout) root.findViewById(R.id.content_frame); 10 View contentView = LayoutInflater.from(this).inflate(getContentResource(), null); 11 content.addView(contentView); 12 if (isMvvM()) binding = DataBindingUtil.bind(contentView); 13 return root; 14} 15 16public <T extends ViewDataBinding> T getBinding() { 17 return (T) binding; 18}

MVVM优势:

  1. UI层、业务层、数据层分工明确实现解耦,维护起来直接找准所需维护层大大减少了代码查找时间以及维护困难;
  2. DataBinding采用了双向绑定技术Model发生变化时View通过viewModel实现自动更新UI;
  3. Controller控制层直接拿到view层减少了控制层代码;

MVVM缺点:

  1. 由于view绑定了数据导致布局无法复用;

你们的点赞、评论就是我更新文章的动力,希望我的文章输出能帮助到一点正在努力中的你,大家一起加油哦!

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Android开发MVVM设计模式的实现及ButterKnife兼容结合源码详解并总结优缺点 - HelloWorld