天天看点

Android Data Binding 技术

       Data Binding

       Data Binding即数据绑定,Data Binding 库实现在布局文件中实现数据绑定申明,使数据的变化引起视图的自动更新,减少了逻辑代码,在Android中可以很方便的实现MVVM的开发模式。

       MVVM

       了解MVVM之前,我们先简单说一下MVC、MVP模式。

       MVC是Model(模型)---View(视图)---(Controller)控制器的缩写,它用一种将业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。将系统进行MVC分层的核心思路就是分离组件,降低组件耦合性,组件独立演化。

Android Data Binding 技术

       MVP是Model--View--Presenter的缩写,MVP与MVC的主要区别是在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。模型与视图完全分离,我们可以修改视图而不影响模型,可以更高效地使用模型,因为所有的交互在Presenter里面。

Android Data Binding 技术

       MVVM是Model-View-ViewModel的缩写,Model提供数据、View负责显示、ViewModel负责逻辑的处理,与MVP的区别是,ViewModel与View之间采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之ViewModel的变化自动引起View的改变 。ViewModel作为View的数据映射,通常View上有什么属性,ViewModel上也会存在相应的一个属性,这两个属性通过事件实现了双向的绑定,Data Binding Library 替我们完成了这样的绑定过程。 MVVM的几个优点:

1. 低耦合: 视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变 化的时候Model可以不变,当Model变化的时候View也可以不变。

2. 可重用性: 你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。

3. 可测试: 界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

Android Data Binding 技术

      环境搭建

Data Binding 插件需要Gradle 1.3以上及Android Studio 1.3.

配置Guide文件:添加Data binding 包路径

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:1.3.0-beta1"
        classpath "com.android.databinding:dataBinder:1.0-rc0"

    }
}
           

然后确保jcenter是在子项目的库列表中       

allprojects {
	   repositories {
   	    jcenter()
	   }
	}      

          在android插件后面添加dataBinding插件

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

   如何使用Data Binding

              支持 Data Binding的布局文件和以前的布局文件不一样,它的跟节点不再是一个ViewGroup,而是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.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"/>
   </LinearLayout>
</layout>
           

            在data节点里面的variable声明实现数据与UI的绑定,变量为UI提供数据,通过@{ } 可以直接把Java 中定义的属性赋值给UI:

<span style="white-space:pre">	</span>android:text="@{user.firstName}
           

         数据对象      

         任何Java对象对象(POJO)可以做数据绑定。

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

         这种绑定以后成员属性改变却不会让UI进行更新。

         要实现成员变更时,UI随着自动更新,首先得有一个实现了 android.databinding.Observable 的类,Android 原生提供了已经封装好的一个类 - BaseObservable,并且实现了监听器的注册机制。 数据类的实现者仍然有责任让成员属性变化时进行通知。这是通过指派一个Bindable注解到getter方法上完成的,并且需要在setter中完成通知动作。   

private static class User extends BaseObservable {
   private String firstName;
   private String lastName;
   @Bindable
   public String getFirstName() {
       return this.firstName;
   }
   @Bindable
   public String getFirstName() {
       return this.lastName;
   }
   public void setFirstName(String firstName) {
       this.firstName = firstName;
       notifyPropertyChanged(BR.firstName);
   }
   public void setLastName(String lastName) {
       this.lastName = lastName;
       notifyPropertyChanged(BR.lastName);
   }
}
           

          BR 是编译阶段生成的一个类,功能与 R.java 类似,用 @Bindable 标记过 getter 方法会在 BR 中生成一个 entry,当我们通过代码可以看出,当数据发生变化时还是需要手动发出通知。 通过调用notifyPropertyChanged(BR.firstName)来通知系统 BR.firstName 这个 entry 的数据已经发生变化,需要更新 UI。

     绑定数据

       默认情况下,一个绑定类会根据布局文件的名称生成一个绑定类,下面代码就是activity_main.xml生成的类ActivityMainBinding.这个类持有所有从布局文件中的View对应的属性(例如:user变量),并且知道如何指派变量值到绑定的表达式中。      

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
   User user = new User("Test", "User");
   binding.setUser(user);
}
           

官方手册:

https://developer.android.com/tools/data-binding/guide.html

继续阅读