目录
DataBingding个人使用很久了,觉得很好用且方便,让自己的代码更加简单且少,读取来更有可读性。建议还未入手的赶紧用起来,真的是方便快捷简单。常规用法很简单,我将使用中需要注意的地方进行一下总结和归纳。本篇文章适合DataBinding的进阶和扩展学习。DataBinding的基础学习地址为:DataBinding中文官方文档
关于DataBinding的基础配置和原理请看:DataBinding的使用(一)
使用注意细节
虽然DataBinding使用简单,但是还有些需要注意的地方,我将在下面意义列举出来。
1.和TextView一样,setText()类似,其中的数据不可是int或者Ingeter(或Int kotlin)、需要转成String
<!--注意:这里age是int类型,必须转化为String,否则会运行时异常-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(user.age)}" />
2.集合中的调用推荐用法
在使用List和Map中[]或者是get()两种写法,官方推荐这种集合框架使用[]的写法
//这里是单引号不是Tab上的点
android:text='@{map["key0"]}'
//或者这样写,注意:里面的 ` 不是单引号,而是Tab键上面的那个键的那个点
android:text="@{map[`key0`]}"
3.java中的表达式支持
android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"
//和上面等价类似,如果user.displayName为null,则右边,否则左边运行
2.还有如下 格式 ??符号相当于三目运算的简写
android:text="@{user.displayName ?? user.lastName}"
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
android:text='@{"iname:" +user.name}'
3.静态方法的使用
<TextView android:text="@{MyStringUtils.capitalize(user.firstName)}" />
有时会报错,此时使用android:text='@{@String/iname +user.name}'这种方式可解决
表达式语言与 Java 表达式有很多相似之处。下面是相同之处:
- 数学计算 + - / * %
- 字符串连接 +
- 逻辑 && ||
- 二进制 & | ^
- 一元 + - ! ~
- 位移 >> >>> <<
- 比较 == > < >= <=
- instanceof
- 组 ()
- 字面量 - 字符,字符串,数字, null
- 类型转换
- 函数调用
- 字段存取
- 数组存取 []
- 三元运算符 ?:
不支持的操作符
一些 Java 中的操作符在表达式语法中不能使用。
- this
- super
- new
- 显式泛型调用 <T>
4.设置别名alias
如果我们import了两个不同路径,但名称相同的类,可以借助于别名来解决,别名借助alias字段来标识
<data>
<import type="com.zx.databindingdemo.bean.UserBean" />
<import type="com.zx.databindingdemo.bean.user.UserBean" alias="UserBean2"/>
<variable
name="user"
type="UserBean" />
<variable
name="user2"
type="UserBean2"/>
</data>
5.include中的数据传递
在使用命名空间的布局中,变量可以传递到任何 include 布局中
<data>
<variable name="user" type="com.example.User"/>
</data>
<include
layout="@layout/contact"
app:user="@{user}"/>
// 可以是app:user或者bind:user,其实都一样的可以
6.Data binding不支持直接包含merge 节点。
//举个例子, 以下的代码不能正常运行 :
<merge>
<include layout="@layout/contact"
app:user="@{user}"/>
</merge>
7.事件处理使用方式
方式一:
android:onClick="@{clickListener}"
方式二:
//使用该种方法时末尾是没有 "()"的,要特别注意
android:onClick="@{handler::onClickFriend}"/>
<!-- 注意:函数名和监听器对象必须对应 -->
<!-- 函数调用也可以使用 `.` , 如handler.onClickFriend , 不过已弃用 -->
方式三
android:onCheckedChanged="@{(view,cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />
等价==
android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />
方式二相对于方式一,它的优势在于表达式会在编译时处理,如果方法不存在或者方法签名不对,编译将会报错。
8.RecyclerView中的闪烁问题
@Override
public void onBindViewHolder(@NonNull UserAdapterHolder holder, int position) {
holder.getBinding().setClassName(beans.get(position));
holder.getBinding().setAdapter(this);
holder.getBinding().setPosition(position);
holder.binding.executePendingBindings();
}
holder.binding.executePendingBindings()这个不加上可能会控件显示异常现象。
9.BindingAdapter注解设置自定义属性
public class ImageHelper {
/**
* 1.加载图片,无需手动调用此方法
* 2.使用@BindingAdapter注解设置自定义属性的名称,imageUrl就是属性的名称,
* 当ImageView中使用imageUrl属性时,会自动调用loadImage方法,
*
* @param imageView ImageView
* @param url 图片地址
*/
@BindingAdapter({"imageUrl"})
public static void loadImage(ImageView imageView, String url) {
Glide.with(imageView.getContext()).load(url)
.placeholder(R.mipmap.fruit)
.error(R.mipmap.fruit)
.into(imageView);
}
}
// 具体的使用形式
<!-- 当imageUrl属性存在时,会自动调用ImageHelper的loadImage方法,
参数imageView为当前使用imageUrl属性的ImageView,参数url为图片地址 -->
<ImageView
android:layout_width="120dp"
android:layout_height="120dp"
android:scaleType="centerCrop"
app:imageUrl="@{user.picUrl}" />
10.onLongClick是有返回值
onLongClick的返回值类型是布尔型,故调用的方法应该也是有返回值且返回Boolean
//等待持续补充
DataBinding 不支持使用@mipmap
在DataBinding中使用@mipmap时,直接会有编译错误,如
android:src="@{isRemoteData?@mipmap/album_download_normal:@mipmap/album_download_disable}" />
对应的结局方案,只需要采取两个步骤就行了。
1. 在xml文件中引入R资源
<import type="com.xuanyuan.photoalbum.R" />
2. 在如ImageView中配置如下
app:imageResource="@{isRemoteData?R.mipmap.album_download_normal:R.mipmap.album_download_disable}"