Android中的Mvvm设计模式这一篇文章就够了

1.DataBinding介绍


     2015年谷歌I/O大会上介绍了一个框架DataBinding,DataBinding是一个数据绑定框架,以前我们在Activity里写很多的findViewById,现在如果我们使用DataBinding,就可以抛弃findViewById。DataBinding主要解决了两个问题: 
- 需要多次使用findViewById,损害了应用性能且令人厌烦 
- 更新UI数据需切换至UI线程,将数据分解映射到各个view比较麻烦

就让我们具体来看看怎么使用它吧。

[注意]:我介绍是基于android stadio1.5及以上开发工具

2.DataBinding的导入

新建MvvMProject项目:
在应用的build.gradle文件中添加如下代码:

android {
    
//其他的一些闭包.....
//使用Mvvm框架只需添加如下闭包配置便可以了
    dataBinding{
        enabled true
    }
}

3.DataBinding基本使用包括以下内容:

  1. 单纯的摆脱findviewbyid
  2. 绑定基本数据类型及String
  3. 绑定Model数据
  4. 绑定事件
  5. 通过静态方法转换数据类型
  6. 通过运算符操作数据
  7. 自定义Binding的类名
  8. 绑定相同Model的操作
  9. model变量改变自动更新数据
  10. 绑定List/Map等集合数据
  11. Observable自动更新
  12. Databinding与include标签的结合
  13. DataBinding与RecyclerView的结合

下面开始:

3.1的内容单纯的拜托findViewById的方法来直接绑定View中的控件,其中activity_main中的代码如下;

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

    <!--把我们需要展示的布局文件写在layout里面-->
    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">

        <Button
            android:id="@+id/main_button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="单纯的摆脱findViewById" />

    </LinearLayout>
</layout>

在MainActivity中如下代码,每行都有注释很好理解

public class MainActivity extends AppCompatActivity {

    //ActivityMainBinding是系统自动生成的
    private ActivityMainBinding activityMainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        //通过我们获取到的Binding.id就可以直接使用布局中的控件了,如下添加一个按钮的点击事件
        activityMainBinding.mainButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "没有findViewById了!", Toast.LENGTH_SHORT).show();
            }
        });
        //这里的SetContentView()方法不在使用了
        //setContentView(R.layout.activity_main);
    }
}

这里我们通过获取到的Binding对象然后就能直接获取到View中的ID然后进行我们想要的操作就可以了。

3.2绑定基本数据类型及String

效果如图:

下面我们继续修改XML文件如下:

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

    <data>
        <!--我们需要绑定的基本数据类型-->
        <!--name:如同Java中的对象是类似的,自己定义名字-->
        <!--type:如同Java中的类型是一样的,如类的概念-->
        <variable
            name="content"
            type="String" />

        <variable
            name="enabled"
            type="boolean" />

    </data>
    <!--把我们需要展示的布局文件写在layout里面-->
    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">

        <!--绑定基本数据类型是通过@{数据类型的对象}来进行数据类型的控制显示-->
        <Button
            android:id="@+id/main_button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="@{enabled}"
            android:text="@{content}" />

    </LinearLayout>
</layout>

在布局中是通过@{}来绑定数据的,{}中是布局中该控件属性对应的数据类型数据,同时还可以支持运算符运算和静态方法调用和转换,这个后面会介绍的。

下面是MainActivity中的代码:

public class MainActivity extends AppCompatActivity {

    //ActivityMainBinding是系统自动生成的
    private ActivityMainBinding activityMainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        //绑定基本数据类型
        activityMainBinding.setContent("对基本数据类型String进行绑定");
        activityMainBinding.setEnabled(true);//这里给控件设置可点击的属性,这里设置false是不可点击

        //其实下面的这个绑定事件是不能用的,因为上面一行设置了可点击false属性
        //通过我们获取到的Binding.id就可以直接使用布局中的控件了,如下添加一个按钮的点击事件
        activityMainBinding.mainButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "其实你点击我是没有用的!", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

这时候点击控件是没有作用效果的额。

3.3绑定Model数据

新建一个JavaBean,取名User只有一个属性用户名。

/**
 * Created by AndyYuan on 2019/4/16.
 * Created time at 2019/4/16.
 */

public class User {
    private String userName;

    public User(String userName) {
        this.userName = userName;
    }

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

    public String getUserName() {
        return userName;
    }
}

布局文件如下:

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

    <data>
        <!--我们需要绑定的基本数据类型-->
        <!--name:如同Java中的对象是类似的,自己定义名字-->
        <!--type:如同Java中的类型是一样的,如类的概念-->
        <variable
            name="user"
            type="com.example.andyyuan.mvvmproject.User" />

    </data>
    <!--把我们需要展示的布局文件写在layout里面-->
    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">

        <!--绑定基本数据类型是通过@{数据类型的对象}来进行数据类型的控制显示-->
        <Button
            android:id="@+id/main_button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.userName}" />

    </LinearLayout>
</layout>

对Model中的数据的操作进行如下:

public class MainActivity extends AppCompatActivity {

    //ActivityMainBinding是系统自动生成的
    private ActivityMainBinding activityMainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        //新建User对象,来进行绑定user对象model数据
        final User user = new User("我是user名字被绑定了");
        //activityMainBinding.setUser(user);
        //绑定数据也可以这样来写
        activityMainBinding.setVariable(BR.user,user);

        activityMainBinding.mainButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this,user.getUserName(),Toast.LENGTH_LONG).show();
            }
        });
    }
}

3.4 绑定事件

效果如下:

下面讲解事件的绑定,这个例子是最简单的事件绑定机制:

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

    <data>
        <!--我们需要绑定的基本数据类型-->
        <!--name:如同Java中的对象是类似的,自己定义名字-->
        <!--type:如同Java中的类型是一样的,如类的概念-->
        <variable
            name="event"
            type="com.example.andyyuan.mvvmproject.EventListener" />

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

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

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

    </data>
    <!--把我们需要展示的布局文件写在layout里面-->
    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical"
        tools:tontext="com.example.andyyuan.mvvmproject.MainActivity">

        <!--绑定基本数据类型是通过@{数据类型的对象}来进行数据类型的控制显示-->
        <Button
            android:id="@+id/main_button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{event::onClick1}"
            android:text="@{button1}" />

        <Button
            android:id="@+id/main_button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{event::onClick2}"
            android:text="@{button2}" />

        <Button
            android:id="@+id/main_button3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{event::onClick3}"
            android:text="@{button3}" />

    </LinearLayout>
</layout>

新建接口EventListener如下:

/**
 * Created by AndyYuan on 2019/4/16.
 * Created time at 2019/4/16.
 */

public interface EventListener {

    void onClick1(View view);

    void onClick2(View view);

    void onClick3(View view);
}

主类中的代码如下:

public class MainActivity extends AppCompatActivity {

    //ActivityMainBinding是系统自动生成的
    private ActivityMainBinding activityMainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //通脱DataBinding设置布局文件后都会返回一个Binding对象,对象的名字是布局文件名后添加Binding
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        activityMainBinding.setButton1("这个是第一个按钮Button1");
        activityMainBinding.setButton2("这个是第二个按钮Button2");
        activityMainBinding.setButton3("这个是第三个按钮Button3");

        activityMainBinding.setEvent(new EventListener() {
            @Override
            public void onClick1(View view) {
                activityMainBinding.setButton1("第一个按钮被点击");
                Toast.makeText(MainActivity.this, "点击了第一个按钮", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onClick2(View view) {
                activityMainBinding.setButton1("第二个按钮被点击");
                Toast.makeText(MainActivity.this, "点击了第二个按钮", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onClick3(View view) {
                activityMainBinding.setButton1("第三个按钮被点击");
                Toast.makeText(MainActivity.this, "点击了第三个按钮", Toast.LENGTH_LONG).show();
            }
        });
    }
}

3.5 通过静态方法转换数据类型

发布了116 篇原创文章 · 获赞 165 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_42618969/article/details/89238632