8、DataBinding表达式与运算符:三元运算符、空合并运算符、集合与数组访问、字符串拼接与格式化
DataBinding 的表达式语法,说白了就是让你在 XML 里写逻辑。很多人刚接触时觉得别扭——「逻辑不该写在 Java/Kotlin 里吗?」我刚开始也这么想。但用久了你会发现,有些简单的 UI 判断,写在 XML 里反而更清爽,不用在代码里写一堆 if-else 和 findViewById。
这一节我们聊几个最常用的运算符和表达式。它们不复杂,但用好了能省不少事。
8.1 三元运算符:最简单的条件判断
三元运算符是 DataBinding 里最常用的条件表达式。格式很简单:条件 ? 真值 : 假值。
<TextView
android:text="@{user.isVIP ? "VIP用户" : "普通用户"}"
android:textColor="@{user.isVIP ? @color/gold : @color/gray}" />
我个人习惯把三元运算符用在颜色、文字、可见性这类简单切换上。比如用户头像的占位符:
<ImageView
android:src="@{user.avatar != null ? user.avatar : @drawable/ic_default_avatar}" />
8.2 空合并运算符:告别空指针
Kotlin 开发者对 ?? 肯定不陌生。DataBinding 里同样支持这个运算符。它的作用是:左边不为空就用左边,否则用右边。
<TextView
android:text="@{user.nickname ?? "未设置昵称"}" />
这比写三元运算符 user.nickname != null ? user.nickname : "未设置昵称" 简洁多了。
我曾经在一个列表页里忘了处理空值,结果用户昵称为 null 时,TextView 直接显示了一行 "null"。嗯,那个版本上线后被吐槽了。后来我养成了习惯——所有展示用户输入字段的地方,都加上 ?? 兜底。
@{(user.nickname != null && !user.nickname.isEmpty()) ? user.nickname : "未设置"}
8.3 集合与数组访问:拿数据就这么简单
DataBinding 支持通过下标访问 List、Array 和 Map。语法和 Kotlin 一样:
<!-- List 或 Array -->
<TextView android:text="@{list[0]}" />
<TextView android:text="@{array[position]}" />
<!-- Map -->
<TextView android:text="@{map["key"]}" />
<TextView android:text="@{map[user.keyField]}" />
我在项目中遇到过这样一个场景:一个商品详情页需要展示规格列表,用户选中某个规格后,价格区域要同步更新。用 DataBinding 的集合访问就很方便:
<TextView
android:text="@{"¥" + specList[selectedIndex].price}" />
你想想看,如果没有 DataBinding,你得写多少代码?先拿到 List,再根据下标取值,再 setText……现在一行搞定。
@{list[viewModel.currentIndex]}。只要变量变化,UI 会自动刷新。
8.4 字符串拼接与格式化
字符串拼接在 DataBinding 里用 + 号就行。但要注意——所有非字符串类型需要显式转换:
<!-- 正确 -->
<TextView android:text="@{"用户:" + user.name + ",年龄:" + String.valueOf(user.age)}" />
<!-- 错误:age 是 int,不能直接拼接 -->
<!-- android:text="@{"年龄:" + user.age}" -->
格式化字符串我推荐用 @string 资源配合占位符。这样更干净,也方便做国际化:
<!-- strings.xml -->
<string name="user_info">用户名:%s,积分:%d</string>
<!-- layout.xml -->
<TextView
android:text="@{@string/user_info(user.name, user.points)}" />
这种写法比在 XML 里拼一大串要优雅得多。我个人的习惯是:超过两个变量的拼接,一律用 @string 格式化。
8.5 知识体系一览
下面这张图把本节涉及的运算符和表达式串了起来。你可以把它当作速查表:
8.6 实战组合:一个完整的例子
把上面这些知识点串起来,看看实际页面怎么写。假设我们要展示一个商品卡片:
<layout>
<data>
<variable name="product" type="com.example.Product" />
<variable name="isLoggedIn" type="boolean" />
</data>
<LinearLayout>
<!-- 商品名称,没有则显示默认文案 -->
<TextView
android:text="@{product.name ?? "未知商品"}" />
<!-- 价格,VIP用户显示金色 -->
<TextView
android:text="@{"¥" + String.valueOf(product.price)}"
android:textColor="@{product.isVIP ? @color/gold : @color/red}" />
<!-- 标签列表,取第一个标签展示 -->
<TextView
android:text="@{product.tags != null && product.tags.size() > 0 ? product.tags[0] : ""}" />
<!-- 购买按钮,未登录显示灰色 -->
<Button
android:enabled="@{isLoggedIn}"
android:text="@{isLoggedIn ? "立即购买" : "请先登录"}" />
</LinearLayout>
</layout>
这个例子涵盖了本节所有知识点。你仔细看——没有一行 Java/Kotlin 代码,所有 UI 逻辑都在 XML 里完成了。这就是 DataBinding 表达式的魅力。
@Bindable 暴露出来。XML 里只做简单的取值和判断,这样维护起来更轻松。
好了,这一节的内容就这些。运算符和表达式是 DataBinding 的基础能力,掌握了它们,你就能写出更简洁、更声明式的布局文件。下一节我们会聊更高级的话题——双向绑定,到时候你会发现,原来数据和 UI 可以配合得这么默契。
公众号:蓝海资料掘金营,微信deep3321