Android DataBinding

Android 团队发布了一个 数据绑定框架(Data Binding Library) 。以后可以直接在 layout 布局 xml 文件中绑定数据了,无需再 findViewById 然后手工设置数据了。其语法和使用方式和 JSP 中的 EL 表达式非常类似。

Data Binding Library 是一个 support 库,支持 Android 2.1+ 版本 (API level 7+)。 由于该框架需要使用编译器来生成很多代码,所以需要配合最新版本的 Android Studio (1.3.0-beta1 + 版本)才能使用。

另外需要注意的是,Data Binding Library 还处于 beta 测试阶段,所以 API 还不稳定,随时可能会修改 API 接口,同时还有很多 BUG, 如果您使用过程中遇到了 bug ,可以到这里反馈: https://code.google.com/p/android-developer-preview/ 。

官方介绍中有一条明确指出android gradle版本必须大于1.5.0-alpha:

To use data binding, Android Plugin for Gradle 1.5.0-alpha1 or  higher is required.

最新版的 Android Studio 已经内置了对 Android Data Binding 框架的支持,配置起来也很简单,只需要在 app 的 build.gradle 文件中添加下面的内容就好了

android {
    ....
    dataBinding {
        enabled = true
    }
}

配置完成之后,等项目构建完成,你会发现项目External Libraries中多了四个aar包:

adapters-1.0-rc3 定义了一些DataBinding的组件

baseLibrary-1.0-rc5 定义了一些DataBinding的annotation和回调接口

compiler-1.0-rc5 定义了一些用于编译DataBinding的工具类

library-1.0-rc3 定义了一些Observable基本类型

四个jar包加起来总共也不会超过200KB。

使用

使用DataBinding库将会改变android传统开发流程中Layout文件的编写方式,这就是ViewModel的核心,将视图和Model绑定在一起,你只需要修改Model层的值,对应的View层就会监听到自动修改自身。

Data Binding Layout文件

android 的res/layout文件下放着应用的全部界面视图,Data Binding Layout文件也是放在该目录下,其实就是修改传统layout文件就可以让它变成一个Data Binding Layout文件。

Data Binding layout 文件有点不同的是:起始根标签是 layout,接下来一个 data 元素以及一个 view 的根元素。这个 view 元素就是你没有使用 Data Binding的layout文件的根元素。举例说明如下:

<?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内描述了一个名为user的变量属性,使其可以在这个layout中使用:

<variable name="user" type="com.example.User"/>

在layout的属性表达式写作 @{},下面是一个 TextView 的 text 设置为 user 的 firstName 属性:

<TextView android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@{user.firstName}"/>

请注意这个layout的文件名,DataBinding会根据这个layout的文件名生成一个xxBinding类,这个类继承自ViewDataBiding;如果layout文件名是content_main.xml,则会生成一个ContentMainBinding类,根据官方解释是自动把layout文件名的下滑线去掉,然后采用驼峰式的命名规则,然后再加上Binding后缀。这也说明了android里的layout编译器会把其转换成一个单独的类,每个layout对应一个layout的类。只不过用DataBinding库把这个layout类转换重新实现过。

Data Object

假设你有一个user的plain-old Java Object(POJO):

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

这个类型的对象拥有从不改变的数据。在 app 中它是常见的,可以读取一次并且之后从不改变。当然也可以使用 JavaBeans 对象:

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;
}
}

从 Data Binding 的角度来看,这两个类是等价的。用于 TextView 中的 android:text 属性的表达式 @{user.firstName} 将访问前者 POJO 对象中的 firstName 和后者 JavaBeans 对象中的 getFirstName() 方法。

绑定数据
 
 
public class MainFragment extends Fragment {
private ContentMainBinding mMainBinding; private UserModel mUserModel; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.content_main, container, false); // 方式1,直接用默认生成的Binding类绑定 mMainBinding = ContentMainBinding.bind(view); // 方式2,向上转成ViewDataBinding类型 // ViewDataBinding viewDataBinding = ContentMainBinding.bind(view); // mMainBinding = (ContentMainBinding) viewDataBinding; //方式3,使用生成的Binding的inflater, // mMainBinding = ContentMainBinding.inflate(inflater); //方式4,使用生成的Binding的inflater,类似Inflater api // mMainBinding = ContentMainBinding.inflate(inflater, container, false); //方式5,某种情况无法生存默认Binding的情况下,并且把对应的layout传入 // ViewDataBinding viewDataBinding = DataBindingUtil.inflate(inflater, R.layout.content_main, container, false); // mMainBinding = (ContentMainBinding) viewDataBinding; //方式6,某种情况无法生存默认Binding的情况下 // ViewDataBinding viewDataBinding = DataBindingUtil.bind(view); mUserModel = new UserModel(this, getResources()); mMainBinding.setUser(mUserModel); attachButtonListener(); return view; }

如果是在Activity中使用方式是:

@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);
}

步骤一:初始化对应layout的Binding类;
步骤二:初始化对应layout的Model类;
步骤三:将对应layout的Model类和Binding类进行绑定;

这里用到了上面layout默认自动生成的Binding类,有很多种不同的API可以初始化Binding类,不同方法在根据不同情况具体调用。

Model类和Binding类的绑定api依赖于data binding layout的配置。这里配置的是:

<variable name="user" type="com.example.User"/>

即variable name=”user” 这里的name属性是user,对应Binding类的setUser方法,这个方法也是默认自动生成的,采用驼峰式。
然后你就可以通过修改UserModel的值达到自动修改View的效果了。

上面演示了最简单的Data Binding库的使用,更深入更高级的使用官方文档已经向我们介绍了。不过要习惯这种模式的开发,还需要一段时间的使用来适应它。

参考资料:http://developer.android.com/intl/zh-cn/tools/data-binding/guide.html
https://realm.io/cn/news/data-binding-android-boyar-mount/?utm_source=tuicool&utm_medium=referral
http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0603/2992.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值