• DataBinding双向绑定简介


    一、简介

           在Vue中使用的是MVVM架构。通过ViewModel可以实现M层和V层数据的双向绑定。Model层的数据发生变化后,会自动更新View层UI。UI层数据发生变化(用户输入),可以驱动Model层的数据发生变化,借助于Vue框架中的ViewModel实现数据和UI的双向驱动。

        在Android中也想实现数据的双向绑定,怎么办呢?

      JetPack中的DataBinding就充当了ViewModel的角色,用来实现数据的双向绑定。

    Android app的开发架构从最开始的MVC到MVP,到MVVM,进一步的解耦。

    在Vue中,开发者只需维护数据的变化就行,数据变化后,会自动刷新UI,大大提示了开发效率。

    Android层面实现MVVM,要比在Vue中复杂些,需要做的准备工作很多。

    在Android中使用DataBinding后,不需要再写findVIewById方法,也不需要调用VIew的setText,

    这也就实现了Model层和VIew层的解耦,在Vue中也不需要手动操作dom来更新UI。

    二、DataBinding在Android中的应用。

        1.app项目中开启DataBinding支持,默认是关闭的。

             builder.gradle ---android节点下配置 

    1. dataBinding {
    2. enabled true
    3. }

        2.编写model层代码JavaBean

          和编写普通JavaBean,除了写get、set方法外有以下不同。

           1)定义的JavaBean需要继承BaseObservable 类

           2)在get方法上添加注解@Bindable,DataBinding需要通过注解来解析定义的方法。

           3)在set方法中添加对应的方法 ,

                 notifyPropertyChanged(BR.age); notifyPropertyChanged(BR.name);

    1. public class User extends BaseObservable {
    2. private String name;
    3. private String age;
    4. @Bindable
    5. public String getName() {
    6. return name;
    7. }
    8. public void setName(String name) {
    9. this.name = name;
    10. notifyPropertyChanged(BR.name);
    11. }
    12. @Bindable
    13. public String getAge() {
    14. return age;
    15. }
    16. public void setAge(String age) {
    17. this.age = age;
    18. notifyPropertyChanged(BR.age);
    19. }
    20. @Override
    21. public String toString() {
    22. return "User{" +
    23. "name='" + name + '\'' +
    24. ", age='" + age + '\'' +
    25. '}';
    26. }
    27. }

      BR是注解处理器(Annotation Processing Tool,简称APT)解析JavaBean生成的类,和android中的R文件类似。编写完JavaBean之后,通过Build生成的类,

    1. package com.example.jetpack;
    2. public class BR {
    3. public static final int User = 1;
    4. public static final int _all = 0;
    5. public static final int age = 2;
    6. public static final int name = 3;
    7. }

    通过以上步骤,完成了MVVM中model层代码的编写。

    3.View层代码的编写。

       1)在普通的layout布局中按下alt+enter键,选择Convert to data binding layout,

            把普通的layout转换成 dataBinding规范的layout

    转换完之后的样式:

        1)根布局变成了layout。

        2)多了一个data标签,这里面可以定义我们编写的JavaBean类,如下:

            name 定义的是View中引用的字符串,可以通过User来获取到里面的值

            type定义的是类型, 可以是基本类型也可以是自定义类型。

    在View中设置值,这一步完成了数据与UI的绑定。通过@{User.name}

    1. <TextView
    2. android:id="@+id/name"
    3. android:layout_width="wrap_content"
    4. android:layout_height="wrap_content"
    5. android:text="@{User.name}"
    6. android:textColor="@color/black"
    7. android:textSize="16sp" />
    8. <TextView
    9. android:id="@+id/age"
    10. android:layout_width="wrap_content"
    11. android:layout_height="wrap_content"
    12. android:text="@{User.age}"
    13. android:textColor="@color/black"
    14. android:textSize="16sp" />

      2)在Activity中

         代替常规写法setContentView(R.layout.activity_data_user);

         通过DataBindingUtil.setContentView(this, R.layout.activity_data_user);把修改后的layout设置在Activity中,返回值是 ActivityDataUserBinding类型,他也是通过APT自动生成的类。

    ActivityDataUserBinding的实现类就是ActivityDataUserBindingImpl

    生成的类名是和定义layout文件名一一对应的。

      

     Activity中完整写法:

    1. private User user;
    2. private int age = 18;
    3. private ActivityDataUserBinding dataBinding;
    4. @Override
    5. protected void onCreate(@Nullable Bundle savedInstanceState) {
    6. super.onCreate(savedInstanceState);
    7. // setContentView(R.layout.activity_data_user);
    8. dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_data_user);
    9. user = new User();
    10. user.setAge(String.valueOf(age));
    11. user.setName("xiaohua");
    12. //通过返回的对象,把User对象设置进去,没有这一步是无法生效的。
    13. dataBinding.setUser(user);
    14. findViewById(R.id.set_user).setOnClickListener(v -> {
    15. //修改user的属性值,界面会自动刷新。
    16. user.setAge(String.valueOf(++age));
    17. user.setName("xiaohua");
    18. });
    19. findViewById(R.id.get_user).setOnClickListener(v -> {
    20. Log.e("nyz", "user " + user.toString());
    21. });
    22. }

    通过以上步骤,就完成了Model到View层的数据绑定,数据发生变化后,UI自动刷新。

    4)DataBinding是如何做到UI发生变化自动更新数据的呢?非常简单。

    通过@={User.name} 可以把获取到的值,复制给User.name,在Java层可以接受到变化后的值。

    这样就完成了View到Model的数据绑定

    1. <EditText
    2. android:id="@+id/name_et"
    3. android:layout_width="wrap_content"
    4. android:layout_height="wrap_content"
    5. android:text="@={User.name}" />
    6. <EditText
    7. android:layout_width="wrap_content"
    8. android:layout_height="wrap_content"
    9. android:text="@={User.age}" />

    具体效果:

       可以看到调用setValue修改User的name和age时,界面中的TextView也跟着更新了,做到了数据驱动UI。

     当通过修改Edittext中的name和age时,TextView中的也更新了,这个就是UI变了,数据跟着变,数据变了,UI跟着变。

    代码下载: https://download.csdn.net/download/niuyongzhi/88382202

  • 相关阅读:
    【无标题】
    域名里边的门道
    window.eventBus 在Vue中的使用方法(一)
    [pai-diffusion]pai的easynlp的diffusion模型训练
    Vue-admin-template关于TagView缓存问题
    Python3 笔记:字符串的 encode() 和 bytes.decode()
    ThreadX任务栈大小确定及其溢出检测方法详解
    第三章 类和对象
    汇编输出命令行参数
    Redis实战——分布式锁
  • 原文地址:https://blog.csdn.net/niuyongzhi/article/details/133377628