zoukankan      html  css  js  c++  java
  • Data Binding

    Data BindingAndroid待发布的支持库,它可以将逻辑和代码关联起来,避免开发者书写大量的胶合代码。

    此前,布局文件XML被认为是相对静态的,往往需要在Java代码中处理与其有关的逻辑;数据绑定技术(Data Binding)改造了布局文件使其能够导入Java类,定义和使用变量,具备像Java代码一样的灵活性,从而使得XML文件变的更加动态化,支持更强大的功能。

    添加依赖

    在项目顶层的gradle中添加依赖

    dependencies {
        classpath "com.android.tools.build:gradle:1.2.3"
        classpath "com.android.databinding:dataBinder:1.0-rc0"
    }

    在具体模块gradle配置文件中启用该插件

    apply plugin: 'com.android.databinding'

    使用示例

    现在有一个User

    public class User {
       public final String firstName;
       public final String lastName;
       public User(String firstName, String lastName) {
           this.firstName = firstName;
           this.lastName = lastName;
       }
    }

    考虑一个专门用来显示User全名TextView,使用数据绑定可以在layout布局文件中就指定其显示的内容为User对象的全名。这个布局文件databinding_layout.xml如下

    //1.根标签为 layout
    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        //2.data标签定义所使用数据域对象
        <data>
            //3.variable标签根据Java类建立变量
            <variable
                name="user" //声明变量名称
                type="com.example.migratingtest.User" //指定变量类型
            />
        </data>
        //4.静态布局
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <TextView
                android:layout_margin="20dp"
                android:padding="20dp"
                android:background="#55ffff00"
                //5.用@{user.firstName}格式使用定义的类对象user
                android:text="@{user.firstName}+@{user.getLastName()}"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    
    </layout>

    布局文件中定义了对象usertextview的对应关系,但要传入的对象user还需要在Java代码中生成;同时这个布局文件将按名称生成一个DatabindingLayoutBinding类,位于appuildintermediatesclassesdebug<包名>databinding目录下,需要在Java代码中作为布局载入;而后将二者绑定起来。

    //1.载入新布局类
    DatabindingLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.databinding_layout);
    //2.产生User对象
    User user = new User("liu", "xiangtian");
    //3.绑定布局和具体对象
    binding.setUser(user);

    更多用法

    布局文件中data可以像Java代码一样导入类,并直接使用其类静态变量/方法,使用variable标签声明和建立对象;

    类和对象的域/方法均可以在布局文件中使用,也支持相关运算,如上例中的字符连接符+

    观察者模式

    上述仅是数据绑定的基本功能,如果User对象一被改变,布局界面就自动更新,数据绑定才显得名副其实。其实现很容易让人联想到观察者模式,User对象继承Observable作为被观察者,但问题是这种实现更新需要主动使用notify函数来通知观察者们;为此,android使用BaseObservable类和Bindable注解实现自动通知。

    要改的仅仅是User类。

    //1.继承BaseObservable类成为被观察者
    public class User extends BaseObservable{
        public String firstName;
    
        //2.给get方法Bindable注解
        @Bindable
        public String getFirstName() {
            return firstName;
        }
        //3.给set方法添加`notify`方法
        public void setLastName(String lastName) {
            this.lastName = lastName;
            notifyPropertyChanged(BR.lastName);
        }
    
    }

    BR亦是编译时生成类,同样位于appuildintermediatesclassesdebug<包名>目录下,其内容是:

    public class BR {
        public static final int _all = 0;
        public static final int firstName = 1;
        public static final int lastName = 2;
        public static final int user = 3;
    }

    此后当使用user.setFirstName("li")更改数据后,布局中将相应变化。

    BR代码可知,User类中所有域均被编入被观察者列表中,这有时并不合理。为了灵活起见,可以使用ObservableFields单独对某个引用域进行转换,使用ObservableInt等对基本类型进行转换。

    依然改User

    public class User {
        public ObservableField<String> firstName = new ObservableField<>();
        public ObservableField<String> lastName = new ObservableField<>();
    }

    在Java代码中初始化User

    User user = new User();
    //ObservableField是一个包装类,提供get/set方法处理包装的内容对象
    user.firstName.set("liu");
    user.lastName.set("xiangtian");

    布局文件仍然使用@{user.firstName}即可,不需要使用@{user.firstName.get}

    绑定关系类

    生成的新布局文件是一个代表绑定关系的类DatabindingLayoutBinding,这个类继承自ViewDataBinding,其中包含所有在布局中声明了的类对象 和 参与绑定的全部View,并提供了相应了set/get方法以及解除所有绑定的unbind方法。如示例中

    // views
    private final android.widget.LinearLayout mboundView0;
    private final android.widget.TextView mboundView1;
    // variables
    private com.example.migratingtest.User mUser;

    原文:http://segmentfault.com/a/1190000004014681
  • 相关阅读:
    [转载]Quartus ii 一些Warning/Eeror分析与解决
    [转载]MAC、IP头、TCP头、UDP头帧格式、详解
    [转载]关于晶振ppm
    20140919-FPGA-有效观察设计中的差分信号
    [转载]转一篇Systemverilog的一个牛人总结
    [转载]ISE中COE与MIF文件的联系与区别
    linux系统性能监控--I/O利用率
    linux系统性能监控--内存利用率
    linux系统性能监控--CPU利用率
    在linux系统中I/O 调度的选择
  • 原文地址:https://www.cnblogs.com/krislight1105/p/4985522.html
Copyright © 2011-2022 走看看