欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android MVVM框架搭建

程序员文章站 2022-07-02 20:34:03
...

Android项目框架分为三种:MVC、MVP、MVVM。这篇文章主要学习一下MVVM的框架搭建。MVVM是基于DataBingding这个工具实现的。
实现效果:
Android MVVM框架搭建
就是在ViewModel中可以修改View层的展示,无需通知View层做任何事情。

1、使用DataBinding

dataBinding{ //放在app项目下的build.gradle中android节点下
        enabled = true
    }

2、创建bean

public class Person {
    public ObservableField<String> name = new ObservableField<>();

    public ObservableField<String> pwd = new ObservableField<>();
}

3、创建MainActivity和布局xml文件

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        new LoginViewModel(viewDataBinding);
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="loginViewModel"
            type="com.example.mvvmtest.LoginViewModel"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:addTextChangedListener="@{loginViewModel.nameListener}"
            android:text="@{loginViewModel.person.name}"
            android:hint="请输入用户名"
             />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入密码"
            android:layout_margin="20dp"
            android:addTextChangedListener="@{loginViewModel.pwdListener}"
            android:text="@{loginViewModel.person.pwd}"
             />

        <Button
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="登录"
            android:onClick="@{loginViewModel.loginClick}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </LinearLayout>
</layout>

tips:上述外围的layout节点,可以将原来的节点直接转换成databingding布局,就会生成外围的layout和data节点。就是在LinearLayout上按快捷键alt+enter,就会出现选项了

4、创建ViewModel

public class LoginViewModel {
    public Person person;
    public LoginViewModel(ActivityMainBinding viewDataBinding) {
        person = new Person();
        viewDataBinding.setLoginViewModel(this);
    }


    public TextWatcher nameListener = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }

        @Override
        public void afterTextChanged(Editable s) {
            person.name.set(String.valueOf(s));
        }
    };

    public TextWatcher pwdListener = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            person.pwd.set(String.valueOf(s));
        }
    };

    public View.OnClickListener loginClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Thread() {
                @Override
                public void run() {
                    person.name.set("123456");
                    try {
                        Thread.sleep(2000);
                        if ("123".equals(person.name)){
                            Log.e("login","login success");
                        }else {
                            Log.e("login","login fail");
                        }

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        }
    };
}

上面基本就写完了。可以看到是ViewModel持有了View的引用,但是View不需要持有ViewModel的引用,只是新建一个对象就可以了。当数据发生变化的时候,无需通知View层做任何变化。
推荐美团做的MVVM Light框架,但是已经四年多没有维护了,可以参考一下。

MVVM的优点:高度解耦,不会产生MVP那样的内存泄露情况
缺点:
1、使用了DataBingding工具,存在坑,据我所知,使用的公司还是很少的(不喜勿喷);
2、还有这个框架很耗内存,在生成的ActivityMainBindingImpl使用了SparseIntArray sViewsWithIds存储xml布局文件中的各个控件,在ViewDataBinding类中有段静态代码块,时刻监测布局,每个布局都要监测,很耗内存,小项目使用可以,大项目使用的话分分钟OOM。
3、使用DataBingding会生成很多文件,使得包大小增大很多,并且无法控制,随着项目增大,伴随的生成文件更多,对于包大小得不偿失。

所以喜欢研究新技术的可以在小项目中使用一下,大项目中慎用,出现坑都不知道因为什么导致的。
代码路径:https://download.csdn.net/download/StudyOfAndroid/12836695

相关标签: android MVVM