android MVVM开发框架——(1)DataBinding 基础应用

概述

Model :基本业务逻辑
View :视图内容
ViewModel: 将前面两者联系在一起的对象

作用

它通过双向绑定(松耦合)解决了Model与View联系比较紧密的问题。
mvvm的双向绑定有一定的局限性,后面会仔细讲到。

配置

android 官方早在Android Studio 1.3、Android Gradle插件1.5之后默认添加了,只需要在项目的build.gradle中配置:

android{
    ...
    dataBinding{
        enabled true
    }
}

如果你的as和gradle插件版本低于上述版本则需要则需要如下操作:
Project 的 build.gradle中添加:classpath ‘com.android.databinding:dataBinder:1.0-rc0’
app 的 build.gradle中添加:apply plugin: ‘com.android.databinding’

Project 的 build.gradle中:

buildscript {
    ...
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
        classpath 'com.android.databinding:dataBinder:1.0-rc0'
    }
}

app 的 build.gradle中:

apply plugin: 'com.android.application'
apply plugin: 'com.android.databinding'

基本使用

1,布局文件。mvvm模式开发布局文件不再是以布局开头了,而是以< layout >开头

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

    <data>
        <!--使用import来导入需要用的包-->
        <import type="com.lh.mvvm.bean.UserBean" />

        <!--使用alias来给包设置别名,用于区别不同包路径下的同名类-->
        <import
            alias="mUtils"
            type="com.lh.mvvm.utils.MvvmUtils" />

        <import type="java.util.ArrayList" />

        <import type="android.databinding.ObservableArrayList" />

        <!--使用关键字variable来声明一个变量,name为变量名,type为指向的对象,可以是类名也可以是类名的别名-->
        <variable
            name="user"
            type="UserBean" />

        <!--泛型的支持会在编译时期报红线,<>需要通过转义字符才行,&lt;数据类型>  -->
        <variable
            name="list"
            type="ArrayList&lt;UserBean>" />

        <!--对于基本类型,可以像java代码一样不用去导入包,直接使用-->
        <variable
            name="postion"
            type="int" />

      <!--  &lt;!&ndash;Observable数据改变自动更新,用于数据和view的双向绑定&ndash;&gt;
        <variable
            name="list1"
            type="ObservableArrayList&lt;UserBean>" />
-->
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <!--使用变量-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.userName}" />

        <!--使用自定义方法-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{mUtils.capitalize(user.userName)}" />

        <!--android:text="@{user.userName != null ? user.userName : user.userAge}"
        等价于
        android:text="@{user.userName ?? user.userAge}"
        -->
        <!--这里不是单引号,是中文字符~符号按出来的,位于Esc按键的下方-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.userName != null ? user.userName : user.userAge + ``}" />

        <!--这里最外层使用单引号,里面需要将其他类型转成字符串的时候,用双引号-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text='@{user.userName ?? user.userAge + ""}' />

        <!--使用资源变量,如果不强转会报错,一般报错信息指明了报错原因-->
        <!--这里的android:visibility="@{user.userId == 1 ? View.GONE : View.VISIBLE}会报错,我们直接用代码所指向的值,一样起作用-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="@{user.userId==1? (int)@dimen/padding_x : (int)@dimen/padding_xx}"
            android:text="@{@string/app_name +`我擦泪`}"
            android:visibility="@{user.userId == 1 ? 0x00000000 : 0x00000008}" />

        <!--获取集合中数据的方式-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{list.get(postion).userName}" />

        <!--List集合既可以和数组一样通过索引获取值list[index]方式,也可以调用API-->
        <Button
            android:id="@+id/btn_test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{list[postion].userName}" />

    </LinearLayout>
</layout>

2,Activity写法

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    ActivityMainBinding activityMainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //它的名字取决于你的layout文件名,activity_main
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        //初始化数据
        UserBean userBean1 = new UserBean(1, "aaa", 1, 1);
        UserBean userBean2 = new UserBean(2, "bbb", 2, 4);
        UserBean userBean3 = new UserBean(3, "ccc", 3, 15);
        ArrayList<UserBean> data = new ArrayList<>();
        data.add(userBean1);
        data.add(userBean2);
        data.add(userBean3);

        //这里的方法和xml中定义的方法相对应
        //赋值过后,控件会自动填充数据
        activityMainBinding.setUser(userBean1);
        activityMainBinding.setList(data);
         //有id的控件也可以通过databinding得到
        activityMainBinding.btnTest.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        if(v.equals(activityMainBinding.btnTest)){
            //修改databinding中的数据
            activityMainBinding.getList().get(0).setUserName("bbb");
             //每一个定义的变量都有相对应的get/set方法activityMainBinding.btnTest.setText(activityMainBinding.getList().get(0).getUserName());
        }
    }
}

基本使用就是这样的,下面看看进阶使用

数据的双向绑定 Observable

再定义一个UserBean

public class UserBean {
    public ObservableInt userId = new ObservableInt();
    public ObservableField<String> userName = new ObservableField<>();
    public ObservableDouble userAge = new ObservableDouble();
    public ObservableFloat userSex = new ObservableFloat();
}

增加main_layout.xml中的代码:

<!--使用alias来给包设置别名,用于区别不同包路径下的同名类-->
        <import
            alias="observableUserBean"
            type="com.lh.mvvm.observable.UserBean" />

<!--双向绑定数据的对象-->
        <variable
            name="observableuser"
            type="observableUserBean" />

<!--双向绑定,当前observableuserbean 下面的数据是双向绑定的,只要数据改变,view中的数据也会跟着改变-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{`双向绑定数据,姓名:`+ observableuser.userName}" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{`双向绑定数据,年龄:`+ observableuser.userAge}" />

activity新增代码:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        com.lh.mvvm.observable.UserBean ouserBean1 = new com.lh.mvvm.observable.UserBean();
        ouserBean1.userId.set(1);
        ouserBean1.userName.set("oaaa");
        ouserBean1.userAge.set(1d);
        ouserBean1.userSex.set(1f);
        activityMainBinding.setObservableuser(ouserBean1);
        activityMainBinding.btnTest1.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        if (v.equals(activityMainBinding.btnTest)) {
            //修改databinding中的数据
            activityMainBinding.getList().get(0).setUserName("bbb");
            //每一个定义的变量都有相对应的get/set方法
            activityMainBinding.btnTest.setText(activityMainBinding.getList().get(0).getUserName());
        } else if (v.equals(activityMainBinding.btnTest1)) {
            //双向绑定数据不需要重新调用控件,数据改变,相对应绑定数据的view也会改变
            activityMainBinding.getObservableuser().userName.set("动态修改后的数据,view自动刷新数据");
            activityMainBinding.getObservableuser().userAge.set(100000);
        }
    }

动态修改数据主要用到了databinding中的Observable对象

Demo下载

发布了113 篇原创文章 · 获赞 48 · 访问量 34万+

猜你喜欢

转载自blog.csdn.net/yehui928186846/article/details/78407543