zoukankan      html  css  js  c++  java
  • <Android 基础(五)> MVVM

    介绍

    MVVM,Model-View-ViewModel,与上次讲的MVP模式比较的类似,MVP中需要大量的接口文件,而MVVM模式下,View和ViewModel直接关联,使用上比较方便,简化了代码,大致的结构图如下:

    这里写图片描述

    可以看待View和ViewModel是双向的交互,这一点很关键

    DataBinding

    Data Binding Library是Google推出的,可以说是针对MVVM模式的支持库,通过在Layout中进行数据的访问,来实现View和Data的双向绑定。不仅使用灵活,用法丰富,而且支持也是相当的广泛,很大程度上降低了代码量和耦合性,减少了开发者的压力。

    build.gradle

        dataBinding {
            enabled= true
        }

    这样使用比较的方法,当然这个需要当前的Gradle版本支持这个属性

    Layout Data

    <?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>
            <import type="com.example.mraz.mvvmdemo.Model.User"></import>
            <variable
                name="user"
                type="User">
            </variable>
        </data>
        <LinearLayout ...
        </LinearLayout>
    </layout>

    最完成使用Layout属性,通过data属性值,添加需要在布局文件中使用的变量和对应的变量类型,也可以先import文件,然后直接使用,不然就需要在type中使用类型的完整路径,当遇到相同的类名的时候,DataBinding支持别名的定义,alias

    Layout Access Data

    布局文件文件中如何实现对绑定数据的访问

                    <TextView
                        android:id="@+id/tv_username"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{user.getUsername()}" />
    
                    <TextView
                        android:id="@+id/tv_password"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{user.getPassword()}" />

    使用格式为“@{ }”,大括号中的使用方式与代码中的基本无差别,可以使用方法,也可以使用对应的成员变量,当然如果权限允许的话,如果要直接访问private变量或者方法,显然是不现实的。

    Activity Set Data

    public class MainActivity extends AppCompatActivity {
        User user = new User("", "");
        @Bind(R.id.et_username)
        EditText etUsername;
        @Bind(R.id.et_password)
        EditText etPassword;
        @Bind(R.id.tv_username)
        TextView tvUsername;
        @Bind(R.id.tv_password)
        TextView tvPassword;
    
        ActivityMainBinding activityMainBinding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            ButterKnife.bind(this);
    }
    
        @OnTextChanged(value = R.id.et_username, callback = OnTextChanged.Callback.TEXT_CHANGED)
        void onUserNameChanged(CharSequence s,int start,int before,int count) {
            user.setUsername(s.toString());
            activityMainBinding.setUser(user);
        }
    
        @OnTextChanged(value = R.id.et_password, callback = OnTextChanged.Callback.TEXT_CHANGED)
        void onPasswordChangedps(CharSequence s,int start,int before,int count) {
            user.setPassword(s.toString());
            activityMainBinding.setUser(user);
        }
    
    }

    几个关键点:
    1. ActivityMainBinding activityMainBinding
    这里定义的变量类型ActivityMainBinding 与布局文件对应
    activity_main ——-> ActivityMainBinding
    first_second ——-> FirstSecondingBinding

    Binding类的命名是基于所述layout文件的名称,用大写开头,除去下划线()以及()后的第一个字母大写,然后添加“Binding”后缀。这个类将被放置在一个模块封装包里的databinding封装包下
    Binding类可通过调整data元素中的class属性来重命名或放置在不同的包中。例如:

    <data class="UserBinding">
        ...
    </data>

    2.activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    获取ActivityMainBinding对象,用于后面设置变量
    3. activityMainBinding.setUser(user);
    设置数据,User变量

    表达式
    常用的表达式和正常的java代码比较类似
    - 数学 + - / * %
    - 字符串连接 +
    - 逻辑 && ||
    - 二进制 & | ^
    - 一元运算 + - ! ~
    - 移位 >> >>> <<
    - 比较 == > < >= <=
    - instanceof
    - 分组 ()
    - null
    - Cast
    - 方法调用
    - 数据访问 []
    - 三元运算 ?:

    不支持的操作:
    this
    super
    new
    显式泛型调用

    实际效果图

    这里写图片描述

    备注:
    关于DataBinding,这里有一篇文章讲得很清晰,推荐一下
    https://segmentfault.com/a/1190000002876984

    效果图对应的代码贴了一部分,实现相对比较容易,这里就不赘述了,如果有需要的留言,我再附上。

  • 相关阅读:
    抽象类和接口的区别
    Overload和Override的区别
    final和finally和finalize的区别
    C#设计模式学习笔记:简单工厂模式(工厂方法模式前奏篇)
    C#设计模式学习笔记:(1)单例模式
    C#设计模式学习笔记:设计原则
    C#加密与解密(DESRSA)学习笔记
    C# IO流与文件读写学习笔记
    C#序列化与反序列化学习笔记
    C#索引器学习笔记
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467201.html
Copyright © 2011-2022 走看看