原文Android resources and attributes cheatsheet, 作者Pavel Dudka
最近, 我碰巧发现了我在早期的Android开发工作中制作的备忘录, 这个备忘录是用来帮助理解Android中设置resources和theme参数时使用的语法的.
我感觉它非常有用, 所以计划重新整理这份备忘并分享给大家.
我们先来看看以下在layout中设置View的背景颜色的不同方法:
android:background="@color/colorPrimary"
android:background="@com.myapp:color/colorPrimary"
android:background="?colorPrimary"
android:background="?attr/colorPrimary"
android:background="?com.myapp:attr/colorPrimary"
android:background="?com.myapp:colorPrimary"
android:background="?android:colorPrimary"
android:background="?android:attr/colorPrimary"
看起来很复杂, 不过看完这篇文章, 你就能看懂它们了.
引用resources vs 引用style
在进一步说明之前, 我们需要先了解@
和?
的区别.
当我们使用@
, 我们是引用了明确的值(颜色, 字符串, 尺寸等). 引用时我们能够知道我们引用的值是多少.
例如:
app/src/main/res/values/color.xml
#3F51B5
所以当我们引用android:background="@color/colorPrimary"
时, 无论当前的theme是什么, 背景色都会被设置为#3F51B5
, 这是一个明确的值.
如果是?
, 则表示我们在引用一个style attribute, 具体的值取决于当前的theme. 例如在一个具体的theme中我可以覆盖这个参数, 所以如果我想改变这个背景色, 我不需要改变layout中的值, 我只需要在theme中覆盖参数, 然后在activity中应用这个theme就可以了.
在上面这个例子里面, 我们告诉Android: "麻烦把当前theme中colorPrimary
的值给我". 这时我们并不能确定返回的值是什么, 因为它取决于Activity当前的theme. 这里如果theme是AppTheme
, 则返回的值会是#F00
.
语法
现在我们来看看引用不同resources的具体语法.
引用resources(@
)
@[package_name:]resource_type/resource_name
-
package_name
- 可选, 指定resource归属的包(默认是app包). 保留的包名 -android
, 用来引用平台resource. -
resource_type
-R.java
中指代resource类型的子类(attr
,color
,string
,dimen
等) -
resource_name
- 引用的resource的具体名称.
现在我们来看看刚才的例子:
android:background="@color/colorPrimary"
android:background="@com.myapp:color/colorPrimary"
实际上, 在默认情况下他们是相等的, 因为package_name
的默认值就是app包, 也就是这里的com.myapp
, 所以第一条中可以省略包名.
- package(可选) =
com.myapp
- resource_type =
color
- resource_name =
colorPrimary
Android为整个OS预定义了一些resources, 因此我们可以通过以下方式引用一些build-in的颜色:
android:background="@android:color/holo_orange_dark"
在这里:
- package =
android
- 引用build-in资源 - resource_type =
color
- resource_name =
holo_orange_dark
注意
现在, 很多人会使用AppCompat(如果你没有, 你应该试试), 而AppCompat常常会定义一些它自己的resources. 尽管AppCompat是Google提供的库, 但是它并不是操作系统的一部分. 相反, 这些resources会被合并进你的app中, 所以引用这些resources不需要使用android
关键字.
例子:
android:background="?selectableItemBackground"
尽管我们没有在app中自定义selectableItemBackground
样式值(注意这里我们没有使用android:
前缀), 我们仍能够获取到值, 因为这个值会被AppCompat"添加"进app中.
引用style attributes(?
)
语法和引用resource非常相似:
?[package_name:][resource_type/]resource_name
不过它们之间有一个不同点.
当引用style attributes时, 这里的resource_type
只能是attr
. 所以, Android packaging tool允许我们忽略resource_type
, 也就是说resource_type
也是可选的.
所以下面的表达式在Android看来实际上是一样的意思:
android:background="?com.myapp:attr/colorPrimary" //完整写法
android:background="?com.myapp:colorPrimary" //省略attr
android:background="?attr/colorPrimary" //省略package
android:background="?colorPrimary" // 省略package & attr
如你所见, 语法非常简单, 妈妈再也不用担心我看不懂了:P
相关链接:
- Official Android documentation
- Dan Lew's talk about theming & styling
- Android Developers Backstage podcast episode about AAPT