Android Data Binding

来源:互联网 发布:熊族看刀路软件下载 编辑:程序博客网 时间:2024/05/16 16:17

Data Binding 解决了 Android UI 编程的一个痛点,官方原生支持 MVVM 模型可以让我们在不改变既有代码框架的前提下,非常容易地使用这些新特性。

使用Data Binding 框架可以让在 Java 代码中直接使用 View 变量的情况会越来越少。

MVVM模型,即Model-View-ViewModel,Model提供数据,View负责显示,ViewModel跟Model和View进行双向绑定;当View有用户输入后,ViewModel通知Model更新数据,同理Model数据更新后,
ViewModel通知View更新

()使用Data Binding准备工作

[1] Android 的 Gradle 插件版本不低于 1.5.0,Gradle 插件版本配置在Project的build.gradle文件中。

classpath 'com.android.tools.build:gradle:1.5.0'

[2]Module的 build.gradle需要配置

.........dataBinding {    enabled true}......

()简单使用

布局文件

使用 Data Binding 之后,xml 的布局文件就不再用于单纯地展示 UI 元素,还需要定义 UI 元素用到的变量。所以,它的根节点不再是一个 ViewGroup,而是变成了 layout,并且新增了一个节点 data。data 节点的作用就像一个桥梁,搭建了 View 和 Model 之间的通路。

<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><data>    <variable        name="user"        type="com.hhb.data_binding.bean.User" /></data><LinearLayout    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="@{user.userName}" /></LinearLayout></layout>

[1]定义 Variable

data 节点中声明一个 User 类型(User中有userName和userPassword属性)的变量 user,type属性用于声明在 Java 文件中定义的 User 类。

data 节点也支持 import。

 <data> <import type="com.hhb.data_binding.bean.User" />    <variable        name="user"        type="User" /></data>

java.lang.* 包中的类会被自动导入,可以直接使用,例如要定义一个 String 类型的变量。

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

[2]Activity绑定 Variable

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);   User user = new User("hhb", "123456");    binding.setUser(user);}

build.gradle 中的插件(com.android.databinding)会根据 xml 文件的名称, 自动创建一个继承自 ViewDataBinding 的类。 但是IDE 中看不到这个文件,需要手动去 build 目录下找。

比如这里 xml 的文件名叫 activity_main.xml,那么生成的类就是 ActivityMainBinding 。

[3]使用 Variable

<TextView        .........        android:text="@{user.userName}" />

()使用类方法(静态方法返回的值)

<data>  <import type="com.hhb.data_binding.util.MyStringUtils" />            ..........</data> <LinearLayout       ......>    <TextView        .......           android:text="@{MyStringUtils.capitalize(user.userPassword)}" /></LinearLayout>

[1]定义静态方法

[2]xml文件的data节点导入

<data>    <import type="com.hhb.data_binding.util.类名" /> </data>

[3]调用

<TextView       ........       android:text="@{类名.方法名(参数)}" />

()区别类名相同

如果我们在 data 节点了导入了两个同名的类怎么办?其实可以通过别名来解决。

<data>    <import type="com.hhb.data_binding.bean.User" />    <import type="com.hhb.data_binding.model.User" alias="ModelUser"/>    <variable name="user"type="User" />    <variable name="muser"type="ModelUser" /></data>

()Null Coalescing 运算符(??)

Null Coalescing操作符会根据左右两侧是否是null进行选择,
如果左侧的不为null,则选择左侧,为null选择右侧。

android:text="@{user.displayName ?? user.lastName}"

等同于:

android:text="@{user.displayName != null ? user.displayName : user.lastName}"

()访问集合类型

集合类型中的元素可以使用[]符号来访问。

  <data>    <import type="com.hhb.data_binding.bean.User" />    <import type="java.util.List" />    <variable        name="user"        type="User" />    <variable        name="userList"        type="List&lt;User>" />    <variable        name="index"        type="int" /></data> <TextView        ............        android:text="@{userList[index].userName}" />

()访问Resource

()Observable Binding

public class User extends BaseObservable {private String userName;........@Bindablepublic String getUserName() {    return userName;}public void setUserName(String userName) {    this.userName = userName;    notifyPropertyChanged(BR.userName);}......}

BR 是编译阶段生成的一个类,功能与 R.java 类似,用 @Bindable 标记过 get方法会在 BR 中生成一个入口。

绑定的对象的值发生变化时还是需要手动发出通知。 通过调用 notifyPropertyChanged(BR.userName) 可以通知系统 BR.userName这个 入口的数据已经发生变化,需要更新 UI。

()获取带有ID的View

使用Data Binding基本上不会再去获取View实例,但是特殊情况下还是需要获取View对象。只要给View定义一个ID,Data Binding就会自动生成一个对应的View对象。

<TextView    android:id="@+id/first_name"    ........ />//获取View对象ActivityMainBinding对象.firstName..setText("liang");

()ViewStubs

xml 中的 ViewStub 经过 binding 之后会转换成 ViewStubProxy。

<layout xmlns:android="http://schemas.android.com/apk/res/android"><LinearLayout    ...>    <ViewStub        android:id="@+id/view_stub"        android:layout="@layout/view_stub"        ... /></LinearLayout></layout>binding = DataBindingUtil.setContentView(this, R.layout.view);binding.viewStub.setOnInflateListener(new ViewStub.OnInflateListener() {@Overridepublic void onInflate(ViewStub stub, View inflated) {    ViewStubBinding binding = DataBindingUtil.bind(inflated);    User user = new User("xx", "xx");    binding.setUser(user);}

});

参考资料:https://github.com/LyndonChin/MasteringAndroidDataBinding

0 0