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优势:
- UI层、业务层、数据层分工明确实现解耦,维护起来直接找准所需维护层大大减少了代码查找时间以及维护困难;
- DataBinding采用了双向绑定技术Model发生变化时View通过viewModel实现自动更新UI;
- Controller控制层直接拿到view层减少了控制层代码;
MVVM缺点:
- 由于view绑定了数据导致布局无法复用;
你们的点赞、评论就是我更新文章的动力,希望我的文章输出能帮助到一点正在努力中的你,大家一起加油哦!