美文网首页
Android MVVM框架

Android MVVM框架

作者: 九馆 | 来源:发表于2019-09-29 14:29 被阅读0次

    MVVM是Model-View-ViewModel的简写,MVVM在MVP的基础上实现了数据视图的绑定(DataBinding),当数据变化时,视图会自动更新;反之,当视图发现变化时,数据也会自动更新。

    M: 负责数据的获取
    V: 负责视图相关(Activity、layout布局文件)
    VM:中间纽带层,负责业务逻辑相关的功能;负责数据的更新,当数据发生变化视图及时更新

    MVVM模型图


    mvvm.png
    View和ViewModel使用DataBinding进行通信的需求实现:

    1.提供View,ViewModel以及Model三层
    2.将布局修改为DataBinding布局
    3.View与ViewModel之间通过DataBinding进行通信
    4.获取数据并展示在界面上

    DataBinding简介

    DataBinding是谷歌官方发布的一个实现数据绑定的框架(实现数据与视图的双向绑定),DataBingding可以帮助我们在安卓中更好的实现MVVM模式

    DataBinding使用步骤

    1.启用DataBinding
    2.修改布局文件为DataBinding布局
    3.数据绑定

    ViewModel和View之间的通信建议使用LiveData + ViewModel的方式

    1.LiveData是一个可以被观察的数据持有者,它可以通过添加观察者的方式来让其他组件观察他的变更。
    2.LiveData遵从应用程序的生命周期,(如果LiveData的观察者已经是销毁状态,LiveData就不会通知该观察者)

    MVVM优点:

    1.实现了数据和视图的双向绑定,极大的简化代码
    2.LiveData更好的解决MVVM之间的通信问题,并且感知组件的生命周期,有效避免内存泄漏

    MVVM缺点:

    1.bug难以调试,并且DataBinding目前还存在一些编译的问题

    DataBinding的基本使用

    布局文件

    <?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="account"
                type="com.example.imooc.framework_mode.bean.Account" />
    
            <variable
                name="activity"
                type="com.example.imooc.framework_mode.databinding.DataBindingActivity" />
    
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            tools:context=".framework_mode.databinding.DataBindingActivity">
    
            <TextView
                android:id="@+id/tv_info"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="80dp"
                android:text="@{account.name + '|' + account.level}"
                tools:text="账号|等级" />
    
            <Button
                android:id="@+id/btn_addLevel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="50dp"
                android:onClick="@{activity.onclick}"
                android:text="账号等级+1" />
    
        </LinearLayout>
    </layout>
    

    实体类

    public class Account extends BaseObservable {
    
        /** 账号名称 */
        private String name;
        /** 账号等级 */
        private int level;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Bindable
        public int getLevel() {
            return level;
        }
    
        public void setLevel(int level) {
            this.level = level;
            notifyPropertyChanged(BR.level);
        }
    }
    

    Activity

    /**
     * DataBinding学习
     * 双向绑定一般适用于输入框(editText)
     *
     * @author Administrator
     */
    public class DataBindingActivity extends AppCompatActivity {
    
        private ActivityDataBindingBinding binding;
        private Account account;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_data_binding);
            binding = DataBindingUtil.setContentView(this, R.layout.activity_data_binding);
    
            account = new Account();
            account.setName("TEST");
            account.setLevel(100);
            binding.setAccount(account);
    
            binding.setActivity(this);
        }
    
        public void onclick(View view) {
    //        Toast.makeText(this, "点击了", Toast.LENGTH_LONG).show();
            int level = account.getLevel();
            account.setLevel(level + 1);
    //        binding.setAccount(account);
    
        }
    }
    
    MVVM框架基本搭建学习

    布局文件

    <?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="viewModel"
                type="com.example.imooc.framework_mode.mvvm.MVVMViewModel" />
    
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context=".framework_mode.normal.NormalActivity">
    
            <!-- @= :数据和视图双向绑定 -->
            <EditText
                android:id="@+id/ed_account"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="50dp"
                android:text="@={viewModel.userInput}"
                android:hint="请输入要查询的账号" />
    
            <Button
                android:id="@+id/btn_get_account"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="80dp"
                android:onClick="@{viewModel.getData}"
                android:text="获取账号信息" />
    
            <TextView
                android:id="@+id/tv_result"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="80dp"
                android:text="@{viewModel.result}"
                android:hint="账号信息暂未获取" />
        </LinearLayout>
    </layout>
    

    实体类

    public class Account extends BaseObservable {
    
        /** 账号名称 */
        private String name;
        /** 账号等级 */
        private int level;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Bindable
        public int getLevel() {
            return level;
        }
    
        public void setLevel(int level) {
            this.level = level;
            notifyPropertyChanged(BR.level);
        }
    }
    

    Model层

    /**
     * 负责数据的获取
     * @author Administrator
     */
    public class MVVMModel {
    
        /**
         * 模拟获取账号数据
         * @param accountName
         * @param callback
         */
        public void getAccountData(String accountName, MCallback callback) {
            Random random = new Random();
            boolean isSuccess = random.nextBoolean();
            if (isSuccess) {
                Account account = new Account();
                account.setName(accountName);
                account.setLevel(100);
                callback.onSuccess(account);
            } else {
                callback.onFailed();
            }
        }
    }
    

    View层

    public class MVVMActivity extends AppCompatActivity {
    
        private ActivityMvvmBinding mvvmBinding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mvvmBinding = DataBindingUtil.setContentView(this, R.layout.activity_mvvm);
            MVVMViewModel mvvmViewModel = new MVVMViewModel(getApplication(), mvvmBinding);
            mvvmBinding.setViewModel(mvvmViewModel);
        }
    }
    

    ViewModel层

    public class MVVMViewModel extends BaseObservable {
    
        private MVVMModel mvvmModel;
        private ActivityMvvmBinding mvvmBindingl;
    
        private String result;
        private String userInput;
        /**
         * 一般需要传入Application对象,方面在ViewModel中使用Application
         * 比如sharedPreferences需要使用
         * @param application
         */
        public MVVMViewModel(Application application) {
            mvvmModel = new MVVMModel();
        }
    
        public MVVMViewModel(Application application, ActivityMvvmBinding binding) {
            mvvmModel = new MVVMModel();
            this.mvvmBindingl = binding;
        }
    
        public void getData(View view) {
            //使用了DataBinding双向绑定,不需要手动获取输入框的数据 注释掉第40行代码
    //        String userInput = mvvmBindingl.edAccount.getText().toString();
            mvvmModel.getAccountData(userInput, new MCallback() {
                @Override
                public void onSuccess(Account account) {
                    String info = account.getName() + "|" + account.getLevel();
                    setResult(info);
                }
    
                @Override
                public void onFailed() {
                    setResult("获取数据失败");
                }
            });
        }
    
        @Bindable
        public String getResult() {
            return result;
        }
    
        public void setResult(String result) {
            this.result = result;
            notifyPropertyChanged(BR.result);
        }
    
        @Bindable
        public String getUserInput() {
            return userInput;
        }
    
        public void setUserInput(String userInput) {
            this.userInput = userInput;
            notifyPropertyChanged(BR.userInput);
        }
    }
    

    相关文章

      网友评论

          本文标题:Android MVVM框架

          本文链接:https://www.haomeiwen.com/subject/iixxpctx.html