Data Binding Library是Google在2015年IO大会上发布的一个用于实现MVVM设计模式的支持库

环境配置

在Android Studio 2.0 原生支持Data Binding框架,配置也变得很简单,只需要在gradle中配置如下脚本即可

android {dataBinding{enabled = true;}
}

布局文件

使用Data Binding后,布局文件也跟以前的有所区别

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><import type="android.view.View"/><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>
标签 说明
layout 布局文件的根节点
data 要实现 MVVM 的 ViewModel 就需要把数据(Model)与 UI(View) 进行绑定,data 节点的作用就像一个桥梁,搭建了 View 和 Model 之间的通路
variable 声明变量
import 导包
@{ } 使用定义的变量

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

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

Includes

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:bind="http://schemas.android.com/apk/res-auto"><data><variable name="user" type="com.example.User"/></data><LinearLayout
       android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><include layout="@layout/name"bind:user="@{user}"/><include layout="@layout/contact"bind:user="@{user}"/></LinearLayout>
</layout>

需要注意的是,Data binding不支持include标签作为merge标签的直接子标签,例如下面的布局是不支持的

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:bind="http://schemas.android.com/apk/res-auto"><data><variable name="user" type="com.example.User"/></data><merge><include layout="@layout/name"bind:user="@{user}"/><include layout="@layout/contact"bind:user="@{user}"/></merge>
</layout>

绑定数据

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);User user = new User("Test", "User");binding.setUser(user);
}
  • 系统会帮我们自动生成一个以xml布局文件名字开始,以Binding结束的类,例如上面的MainActivityBinding.java,另外还会生成一个BR文件,类似于R文件。
  • 除了使用框架自动生成的 MainActivityBinding,我们也可以通过如下方式自定义类名
<data class="com.example.CustomBinding">
</data>

use data binding items inside a ListView adapter

1、BaseAdapter

class CommonAdapter<T> extends BaseAdapter{private List<T> mList;private Context mContext;private int layoutId;private int variableId;public CommonAdapter(List<T> list, Context context, int lauoutId, int variableId) {mList = list;mContext = context;this.layoutId = lauoutId;this.variableId = variableId;}@Overridepublic int getCount() {return mList.size();}@Overridepublic Object getItem(int position) {return mList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewDataBinding binding = null;if (convertView == null){binding = DataBindingUtil.inflate(LayoutInflater.from(mContext),layoutId,parent,false);}else {binding = DataBindingUtil.getBinding(convertView);}binding.setVariable(variableId,mList.get(position));return binding.getRoot();}}

2、布局文件
ListView的item布局

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><data><variable
            name="user"type="com.google.demo.model.User"/></data><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageView
            android:layout_width="wrap_content"android:layout_height="wrap_content"app:imageUrl="@{user.icon}"/><TextView
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.name}"/></LinearLayout>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><data><variable
            name="adapter"type="android.widget.BaseAdapter"/></data><ListView
        android:layout_width="match_parent"android:layout_height="match_parent"app:adapter="@{adapter}"/><!--因为ListView有setAdapter()方法,所以这里可以使用app:adapter属性-->
</layout>

3、逻辑代码

 LayoutLvBinding binding = DataBindingUtil.setContentView(this, R.layout.layout_lv);List<User> list = new ArrayList<>();CommonAdapter<User> adapter = new CommonAdapter<>(list,this,R.layout.lv_item, com.google.demo.BR.user);binding.setAdapter(adapter);

Observable Objects

private static class User extends BaseObservable {private String firstName;private String lastName;@Bindablepublic String getFirstName() {return this.firstName;}@Bindablepublic String getLastName() {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);}
}
  • BaseObservable:实现数据的更新同步到UI控件上需要实现该接口
  • @Bindable注解标记过 的getter 方法会在 BR 中生成一个 entry
  • notifyPropertyChanged(BR.firstName)通知View更新

ObservableFields

private static class User {public final ObservableField<String> firstName =new ObservableField<>();public final ObservableField<String> lastName =new ObservableField<>();public final ObservableInt age = new ObservableInt();
}

ObservableField, ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat, ObservableDouble, and ObservableParcelable

Observable Collections

ObservableArrayMap

ObservableArrayMap<String, Object> user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);

在布局文件中使用

<data><import type="android.databinding.ObservableMap"/><variable name="user" type="ObservableMap&lt;String, Object>"/>
</data>
…
<TextView
   android:text='@{user["lastName"]}'android:layout_width="wrap_content"android:layout_height="wrap_content"/>
<TextView
   android:text='@{String.valueOf(1 + (Integer)user["age"])}'android:layout_width="wrap_content"android:layout_height="wrap_content"/>

ObservableArrayList

ObservableArrayList<Object> user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);

在布局文件中使用

<data><import type="android.databinding.ObservableList"/><import type="com.example.my.app.Fields"/><variable name="user" type="ObservableList&lt;Object>"/>
</data>
…
<TextView
   android:text='@{user[Fields.LAST_NAME]}'android:layout_width="wrap_content"android:layout_height="wrap_content"/>
<TextView
   android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'android:layout_width="wrap_content"android:layout_height="wrap_content"/>

生成Binding class

所生成的Binding类都继承自ViewDataBinding

MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater);
MyLayoutBinding binding = MyLayoutBinding.inflate(layoutInflater, viewGroup, false);
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId,parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bind(viewRoot, layoutId);

绑定事件

public class MyHandlers {public void onClickFriend(View view) { ... }public void onClickEnemy(View view) { ... }
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variable name="handlers" type="com.example.Handlers"/><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}"android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.lastName}"android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/></LinearLayout>
</layout>

使用资源数据

android:padding="@{large? (int)@dimen/largePadding : (int)@dimen/smallPadding}"

Null Coalescing Operator

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

等价于

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

集合的使用

<data><import type="android.util.SparseArray"/><import type="java.util.Map"/><import type="java.util.List"/><variable name="list" type="List&lt;String>"/><variable name="sparse" type="SparseArray&lt;String>"/><variable name="map" type="Map&lt;String, String>"/><variable name="index" type="int"/><variable name="key" type="String"/>
</data>
…
android:text="@{list[index]}"
…
android:text="@{sparse[index]}"
…
android:text="@{map[key]}"

Custom Setters

@BindingAdapter({"imageUrl"})
public static void loadImage(ImageView iv,String url){if (url == null){iv.setImageResource(R.mipmap.ic_launcher);}else {Glide.with(iv.getContext()).load(url).into(iv);}}

Converters(转换器)

@BindingConversion
public static ColorDrawable convertColorToDrawable(int color) {return new ColorDrawable(color);
}
<View
   android:background="@{isError ? @drawable/error : @color/white}"android:layout_width="wrap_content"android:layout_height="wrap_content"/>

DataBindingComponent

所有被注解@BindingAdapter标记的方法,如果该方法为非静态方法,那么都需要一个Component对象,而所需要的Component对象由DataBindingComponent提供,所以我们需要自定义类实现DataBindingComponent接口

public class Utils {@BindingAdapter({"imageUrl"})public static void loadImage(ImageView iv,String url){if (url == null){iv.setImageResource(R.mipmap.ic_launcher);}else {Glide.with(iv.getContext()).load(url).into(iv);}}
}
public class MyComponent implements android.databinding.DataBindingComponent {private Utils mUtils@Overridepublic Utils getUtils() {if (mUtils == null){mUtils = new Utils();}return mUtils;}}

在DataBindingUtil.setContentView()之前设置Component

DataBindingUtil.setDefaultComponent(new MyComponent());

参考

https://github.com/LyndonChin/MasteringAndroidDataBinding

Data Binding Library数据绑定框架相关推荐

  1. Data Binding Library

    本文翻译自文章:Data Binding Library 翻译人员:麦田里的守望者-Lost 例子下载地址:DataBinding-Example 这篇文章介绍了如何使用Data Binding Li ...

  2. Android Data Binding Library 官方文档(译)

    地址:https://developer.android.google.cn/topic/libraries/data-binding/index.html 本文地址:http://blog.csdn ...

  3. Android官方数据绑定框架DataBinding(一)

    还记得在博客<高逼格UI-ASD(Android Support Design)>的开始曾经说过,Android最新推出了一个官方的数据绑定框架-Data Binding Library. ...

  4. WPF中的数据绑定Data Binding使用小结

    完整的数据绑定的语法说明可以在这里查看: http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料: Data Binding: Part 1 http:// ...

  5. XAML数据绑定(Data Binding)

    XAML数据绑定(Data Binding) Data Binding可以使得XAML标签属性的赋值更为灵活和方便.在绑定过程中,获取数据的标签成为目标标签:提供数据的标签成为源标签.在XAML中,一 ...

  6. Android数据绑定框架DataBinding用法

    Android数据绑定框架DataBinding用法     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/5195374 ...

  7. Android开发之关于MVVM架构中视图数据绑定框架dataBinding的基本用法

    dataBinding是Google官方开发的第三方视图数据绑定框架.优缺点如下: 优点:很好用 缺点:调试bug不易,部分AS版本中不太友好 首先说下如何使用: 在gradle中的android模块 ...

  8. Android Data Binding 详细介绍与使用

    构建环境 首先,确保能使用Data Binding,需要下载最新的 Support repository.否则可能报错,如图: 在模块的build.gradle文件中添加dataBinding配置 a ...

  9. Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

    本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...

最新文章

  1. eclipse提示jre_给新手 Java 开发者的 7 点提示 | Linux 中国
  2. 2019年安徽省模块七满分多少_二级造价考情分析:20年二级造价考试还有戏吗?...
  3. mysql5.6.37驱动_MySql (mysql-5.6.37) 在Windows的安装及使用
  4. 【转帖】dopod touch diamond 应用小常识:)
  5. xml 数字签名 破解_JAVA中带有数字签名的XML安全性
  6. [转载] Java中Array(数组)转List(集合类)的几种方法
  7. 爬虫-获取访问后可见的页面-get方法cookies参数形式
  8. 霸气!Power 支持混合云、多云,性能完胜 x86!
  9. 利用数组求前n个质数
  10. 鸿蒙OpenHarmony hi3516开发板,标准系统实现智能门禁
  11. Linux 2038年问题
  12. 英文数据集txt_【美股量化07篇】Python获取标普500成分股数据
  13. Latex 摘要部分
  14. 使用ffmpeg合并多个视频文件
  15. python 点点滴滴
  16. 小米世界第三,华为首次跌出前五
  17. 总结numpy中的ndarray,非常齐全
  18. DELL-R730服务器U盘安装操作系统指南
  19. 蜂巢贷:车抵贷款和房屋抵押贷款的区别
  20. 游戏角色ai的实现方式讨论

热门文章

  1. 3月第3周新闻回顾:3Com案三日动荡 珊瑚虫作者入狱3年
  2. SD-WAN技术分析—Vecloud
  3. 搞不懂SDN和SD-WAN?那是因为你没看这个小故事—Vecloud微云
  4. Android Studio上手,基于VideoView的本地文件及流媒体播放器
  5. 第八章 Python类中常用的特殊变量和方法
  6. 2019.4.1考试2019.4.2考试2019.4.4考试
  7. 力扣——所有可能的满二叉树
  8. django模板中使用JQ代码实现瀑布流显示效果
  9. 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?...
  10. 使用Apache Archiva管理Maven仓库