9、DataBinding资源引用:引用String资源、引用Dimen资源、引用Color资源、引用Plurals复数资源

各位同学,咱们今天聊点实在的。DataBinding 除了绑定数据,还有一个很实用的功能——直接引用 Android 资源文件。说白了,就是你在布局文件里就能拿到 strings.xmlcolors.xmldimens.xml 里的值,甚至还能处理复数资源。这功能我刚开始用的时候觉得挺新鲜,后来发现它确实能省不少事。

核心要点:DataBinding 的资源引用机制,让你在 XML 布局中直接使用 @{} 语法引用资源,无需在 Activity 或 Fragment 中手动获取。

9.1 引用 String 资源

先说说最常用的字符串引用。你可能会问:直接在布局里写死字符串不行吗?当然可以,但为了国际化,我们通常把字符串放在 strings.xml 里。DataBinding 让这件事变得特别自然。

我记得第一次在项目里用这个特性时,团队里还有人质疑:“直接在 XML 里写 @string/app_name 不就行了?干嘛要用 DataBinding?” 嗯,区别在于:当你需要拼接字符串、或者根据数据动态显示不同文案时,DataBinding 的 @{} 语法就派上用场了。

<!-- strings.xml -->
<string name="welcome_message">欢迎回来,%s!</string>
<string name="user_count">当前在线用户:%d 人</string>

<!-- activity_main.xml -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="userName" type="String" />
        <variable name="onlineCount" type="int" />
    </data>
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@string/welcome_message(userName)}" />
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@string/user_count(onlineCount)}" />
    </LinearLayout>
</layout>

看到没?@{@string/welcome_message(userName)} 这种写法,就是把 userName 变量传进字符串占位符里。我个人习惯把这种带参数的字符串引用叫做“智能字符串”,因为它能根据数据自动变化。

小技巧:如果字符串里没有占位符,直接写 @{@string/app_name} 就行。有占位符时,括号里传参数,多个参数用逗号隔开。

9.2 引用 Dimen 资源

尺寸资源在 Android 开发中很常见,比如边距、字体大小、控件宽高。DataBinding 里引用 Dimen 资源,语法和 String 类似,但有个坑——我踩过。

<!-- dimens.xml -->
<dimen name="margin_normal">16dp</dimen>
<dimen name="text_size_title">20sp</dimen>

<!-- 布局文件 -->
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@{@dimen/margin_normal}"
    android:textSize="@{@dimen/text_size_title}"
    android:text="Hello World" />

看起来很简单对吧?但注意:Dimen 资源引用返回的是 float 类型,不是 int。我曾经在设置 android:padding 时直接用了 @{@dimen/margin_normal},结果编译报错。为什么?因为 padding 属性期望的是 dimension 类型,而 DataBinding 表达式返回的是 float,需要显式转换。

避坑指南:我曾经在项目里直接写 android:padding="@{@dimen/margin_normal}",结果编译报错。正确做法是:android:padding="@{@dimen/margin_normal}" 其实是可以的,但如果你在自定义属性或某些特殊场景下,可能需要用 @dimen/margin_normal 直接引用,而不是通过 DataBinding 表达式。记住:能用原生 @dimen/xxx 的地方,尽量别用 @{@dimen/xxx},除非你需要动态计算。

9.3 引用 Color 资源

颜色引用也是高频操作。DataBinding 里引用 Color 资源,语法是 @{@color/color_name}。但这里有个细节:返回的是 int 类型的颜色值,不是 ColorDrawableColorStateList

<!-- colors.xml -->
<color name="primary">#FF6200EE</color>
<color name="primary_dark">#FF3700B3</color>

<!-- 布局文件 -->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="重要提示"
    android:textColor="@{@color/primary}"
    android:background="@{@color/primary_dark}" />

你想想看,如果不用 DataBinding,你得在 Activity 里写 getResources().getColor(R.color.primary),然后通过 setTextColor() 设置。现在一行代码搞定,是不是清爽多了?

注意:如果你需要引用 ColorStateList(比如按钮在不同状态下的颜色),DataBinding 也支持:@{@color/btn_selector}。但返回的是 ColorStateList 对象,不是 int

9.4 引用 Plurals 复数资源

复数资源是 Android 里比较特殊的一种资源。它根据数量自动选择单复数形式。比如“1条消息”和“3条消息”,英文里是 “1 message” 和 “3 messages”,中文虽然没这么复杂,但有些场景还是需要的。

我记得在做一个社交应用时,需要显示“xx人赞了这条动态”。1个人时显示“1人赞了”,多人时显示“N人赞了”。用 Plurals 资源配合 DataBinding,简直完美。

<!-- plurals.xml -->
<plurals name="like_count">
    <item quantity="one">%d 人赞了</item>
    <item quantity="other">%d 人赞了</item>
</plurals>

<!-- 布局文件 -->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{@plurals/like_count(likeCount)}" />

等等,这里有个坑。上面这种写法 编译会报错。为什么?因为 @plurals 资源引用需要指定数量参数,但 DataBinding 的语法是 @{@plurals/resource_name(count)},其中 countint 类型变量。但实际使用时,你还需要传入格式化参数。

正确写法是这样的:

<!-- 正确写法 -->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{@plurals/like_count(likeCount, likeCount)}" />

第一个 likeCount 是用于选择单复数的数量,第二个 likeCount 是传入占位符 %d 的参数。说白了,就是 第一个参数决定用哪个复数形式,后面的参数用于格式化字符串

避坑指南:我曾经在这里卡了半小时。如果你只传一个参数,比如 @{@plurals/like_count(likeCount)},编译不会报错,但运行时会显示 %d 人赞了 这样的原始字符串,因为 %d 没有被替换。记住:Plurals 资源引用至少需要两个参数:第一个是数量选择器,后面是格式化参数

9.5 资源引用综合示例

咱们来个综合的例子,把上面几种资源引用串起来。假设我们要做一个用户信息卡片:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="user" type="com.example.User" />
        <variable name="followerCount" type="int" />
    </data>
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@{@dimen/margin_normal}"
        android:background="@{@color/card_background}">
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@string/welcome_message(user.name)}"
            android:textColor="@{@color/primary}"
            android:textSize="@{@dimen/text_size_title}" />
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@plurals/follower_count(followerCount, followerCount)}"
            android:textColor="@{@color/secondary_text}"
            android:textSize="@{@dimen/text_size_body}" />
    </LinearLayout>
</layout>

这个例子展示了:

  • String 资源带参数引用
  • Dimen 资源用于边距和字体大小
  • Color 资源用于文字和背景颜色
  • Plurals 资源处理复数文案

你看,一个布局文件就把所有资源引用都覆盖了。不用写一行 Java/Kotlin 代码,UI 就动态展示出来了。我个人觉得,这种写法特别适合 MVVM 架构,ViewModel 只管提供数据,布局文件负责展示,各司其职。

9.6 资源引用知识体系

为了让你更直观地理解 DataBinding 资源引用的全貌,我画了一张图:

DataBinding 资源引用体系 DataBinding 资源引用 String 资源 Dimen 资源 Color 资源 Plurals 资源 语法 @{@string/name} @{@string/name(param)} 返回类型:String 支持占位符 %s, %d 多参数用逗号分隔 语法 @{@dimen/name} 返回类型:float 用于 padding、margin 用于 textSize 注意单位转换 语法 @{@color/name} 返回类型:int 用于 textColor 用于 background 支持 ColorStateList 语法 @{@plurals/name(n, n)} 返回类型:String 第一个参数:数量选择 后续参数:格式化 支持 one/other 等

这张图把四种资源引用的语法和返回值都列出来了。你写代码时如果忘了,回来看看这张图就行。

9.7 避坑总结

最后,我把这些年踩过的坑总结一下:

资源类型 常见错误 正确做法
String 忘记传参数,导致显示 %s 有占位符时,括号内传对应参数
Dimen 在需要 dimension 类型的地方用 float 能用原生 @dimen/xxx 就用原生
Color 混淆 int 和 ColorStateList 普通颜色用 @{@color/xxx},selector 用 @{@color/xxx}
Plurals 只传一个参数,%d 没被替换 至少传两个参数:数量 + 格式化参数

嗯,关于 DataBinding 的资源引用,今天就聊这么多。这些技巧我在实际项目中反复用过,确实能提升开发效率。你写代码时多试试,很快就能上手。


公众号:蓝海资料掘金营,微信deep3321