Android设计模式之MVVM

简介

在开发中可能你使用过MVP设计模式来对代码进行解耦,但是谷歌发布的DataBinding库更加简化了我们的代码,同时也催生了MVVM设计模式在Android中的使用。在MVP模式中我们需要ModelViewPresenter三者进行配合使用,而MVVM模式是由ModelViewViewModel进行配合的,其中的区别主要在于ViewModelDataBinding是一个实现数据和UI绑定的框架,是构建MVVM模式的一个关键的工具,其奇妙之处在于可以将XML文件与指定的JAVA类绑定,实现数据的自动更新效果。

MVVMMVP的演进版本,其核心是实现了双向绑定,主要依赖于Android提供的DataBinding兼容库实现。在MVVM中将MVPPresenter替换为ViewModel,而ViewModel相当于UIModel的桥梁,将ViewModel直接绑定并将相关的业务逻辑下移于Model层中进行处理。

mvp

mvvm

Model:负责数据实现和逻辑处理。
View:对应于Activityxml,负责View的绘制以及与用户交互。
ViewModel:创建关联,将ModelView绑定起来,如此之后Model更改后通过ViewModel反馈给ViewViewxml布局文件经过特定的编写及编译工具处理后,生成的代码会接收ViewModel的数据通知消息,自动刷新界面。

单向绑定中数据的流向是单方面的,只能从代码流向UI,而双向绑定的数据流向是双向的,当业务代码中的数据改变时,UI上的数据能够得到刷新,当用户通过UI交互编辑了数据时,数据的变化也能自动的更新到业务代码中的数据上。对于双向绑定可以使用DataBinding,它是一个实现数据和UI绑定的框架,是构建MVVM模式的一个关键的工具。

基本用法

1、环境要求

1、Android Studio版本在1.3以上;
2、gradle的版本要在1.5.0-alpha1以上;
3、需要在Android SDK Manager中下载Android Support Repository
4、在对应Modulebuild.gradle中添加:

android {
    ......
    dataBinding {
        enabled = true
    }
    ......
}

2、创建实体类

public class User {

    private String userName;
    private String nickName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }
}

3、XML布局

布局文件不再是以传统的某一个容器作为根节点,而是使用<layout></layout>作为根节点,在<layout>节点中我们可以通过<data>节点来引入我们要使用的数据源。

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

    <data>

        <variable
            name="user"
            type="com.wiggins.mvvm.bean.User" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/theme_bg"
        android:orientation="vertical">

    <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@{user.userName}"
            android:textColor="@color/blue"
            android:textSize="@dimen/font_normal" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="@{user.nickName}"
            android:textColor="@color/blue"
            android:textSize="@dimen/font_normal" />

    </LinearLayout>
</layout>

4、定义variable

<data>节点中定义的variable节点,其中name属性表示变量的名称,type属性表示这个变量的类型,实例就是我们实体类的具体位置,当然data节点也支持import,所以上面的代码也可以换一种形式来写。

<data>

    <import type="com.wiggins.mvvm.bean.User" />

    <variable
        name="user"
        type="User" />
</data>

使用import节点将User导入,然后直接使用即可。

然后我们前面在build.gradle中添加的dataBinding会根据xml文件的名称Generate一个继承自ViewDataBinding的类。

例如:这里xml的文件名叫activity_main.xml,那么生成的类就是ActivityMainBinding

注意:

java.lang.*包中的类会被自动导入,可以直接使用,例如要定义一个String类型的变量:

<variable
    name="name"
    type="String" />

5、绑定variable

修改ActivityonCreate方法,用DataBindingUtil.setContentView()来替换掉以前的setContentView(),然后使用之前创建的User对象,通过binding.setUser(user)variable进行绑定。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    User user = new User();
    user.setUserName("小明");
    user.setNickName("一花一世界");
    binding.setUser(user);
}

其中的ActivityMainBinding类是DataBinding框架为我们自动生成的,它与你的XML文件名字相关。比如我的XML文件名字是activity_main,那么生成的类就会取消下划线并且在最后加上Binding就得到了ActivityMainBinding。这个类的实例可以通过DataBindingUtil.setContentView()来得到,同时此类里面有我们XML文件里所有的控件信息,因此也不需要去findViewById了,界面上的管理基本可以全部转移到绑定的ViewModel中了,可以参考以下方式对相应的控件进行操作。

binding.tvContent.getText().toString().trim();

注意:

ActivityMainBinding类是自动生成的,所有的set方法也是根据variable名称生成的。例如我们定义了以下两个变量:

<data>
    <variable name="userName" type="String" />
    <variable name="nickName" type="String" />
</data>

那么就会生成对应的两个set方法。

setUserName(String userName);
setNickName(String nickName);

6、使用variable

数据与variable绑定之后,xmlUI元素就可以直接使用了。

<TextView
    android:id="@+id/tv_content"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:gravity="center"
    android:text="@{user.nickName}"
    android:textColor="@color/blue"
    android:textSize="@dimen/font_normal" />

在布局文件中,TextViewtext属性设置成了@{user.nickName},这样该TextView就会直接将User实体类的nickName属性值显示出来了。

基本运算

1、三目运算

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@{user.userName??user.nickName}"
    android:textColor="@color/blue"
    android:textSize="@dimen/font_normal" />

两个??表示如果userNamenull则显示nickName,否则显示userName

2、字符拼接

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@{
    `userName is : `+user.userName}"
    android:textColor=
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值