Data Binding

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

       MVVM

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

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

  

android 查看view是否可视 安卓viewbinding_android 查看view是否可视

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

             

android 查看view是否可视 安卓viewbinding_MVVM DataBinding_02

       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 查看view是否可视 安卓viewbinding_User_03

      环境搭建

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

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



[plain]  view plain copy print ?



    1. buildscript {  
    2.     repositories {  
    3.         jcenter()  
    4.     }  
    5.     dependencies {  
    6.         classpath "com.android.tools.build:gradle:1.3.0-beta1"  
    7.         classpath "com.android.databinding:dataBinder:1.0-rc0"  
    8.   
    9.     }  
    10. }


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


    <span style="font-size: 18px;"><span class="pln"><span style="white-space: pre;">	</span>allprojects </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln">
    <span style="white-space: pre;">	</span>   repositories </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln">
       <span style="white-space: pre;">	</span>    jcenter</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln">
    <span style="white-space: pre;">	</span>   </span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln">
    </span><span class="pun" style="color: rgb(102, 102, 0);"><span style="white-space: pre;">	</span>}</span></span>


               在android插件后面添加dataBinding插件

    <span class="pln"><span style="white-space: pre;">	</span>apply plugin</span><span class="pun" style="color: rgb(102, 102, 0);">:</span><span class="pln"> </span><span class="pun" style="color: rgb(102, 102, 0);">‘</span><span class="pln">com</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln">android</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln">application</span><span class="str" style="color: rgb(136, 0, 0);">'
    <span style="white-space: pre;">	</span>apply plugin: '</span><span style="color: inherit;"><span class="pln">com</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln">android</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln">databinding</span></span><span class="str" style="color: rgb(136, 0, 0);">'</span>


       如何使用Data Binding


                  支持 Data Binding的布局文件和以前的布局文件不一样,它的跟节点不再是一个ViewGroup,而是layout,并且多了一个data节点。 



    [plain]  view plain copy print ?


    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <layout xmlns:android="http://schemas.android.com/apk/res/android">  
    3.    <data>  
    4.        <variable name="user" type="com.example.User"/>  
    5.    </data>  
    6.    <LinearLayout  
    7.        android:orientation="vertical"  
    8.        android:layout_width="match_parent"  
    9.        android:layout_height="match_parent">  
    10.        <TextView android:layout_width="wrap_content"  
    11.            android:layout_height="wrap_content"  
    12.            android:text="@{user.firstName}"/>  
    13.        <TextView android:layout_width="wrap_content"  
    14.            android:layout_height="wrap_content"  
    15.            android:text="@{user.lastName}"/>  
    16.    </LinearLayout>  
    17. </layout>


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


    [plain]  view plain copy print ?


    1. <span >    </span>android:text="@{user.firstName}

         数据对象

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



    [java]  view plain copy print ?


    1. public class User {  
    2. private final String firstName;  
    3. private final String lastName;  
    4. public User(String firstName, String lastName) {  
    5. this.firstName = firstName;  
    6. this.lastName = lastName;  
    7.    }  
    8. public String getFirstName() {  
    9. return this.firstName;  
    10.    }  
    11. public String getLastName() {  
    12. return this.lastName;  
    13.    }  
    14. }

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

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



    [java]  view plain copy print ?


    1. private static class User extends BaseObservable {  
    2. private String firstName;  
    3. private String lastName;  
    4. @Bindable  
    5. public String getFirstName() {  
    6. return this.firstName;  
    7.    }  
    8. @Bindable  
    9. public String getFirstName() {  
    10. return this.lastName;  
    11.    }  
    12. public void setFirstName(String firstName) {  
    13. this.firstName = firstName;  
    14.        notifyPropertyChanged(BR.firstName);  
    15.    }  
    16. public void setLastName(String lastName) {  
    17. this.lastName = lastName;  
    18.        notifyPropertyChanged(BR.lastName);  
    19.    }  
    20. }


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

         绑定数据

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


    [java]  view plain copy print ?



      1. @Override  
      2. protected void onCreate(Bundle savedInstanceState) {  
      3. super.onCreate(savedInstanceState);  
      4. this, R.layout.main_activity);  
      5. new User("Test", "User");  
      6.    binding.setUser(user);  
      7. }

      官方手册:

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