Android访问资源与属性之 ? , @
在Android xml中访问资源和样式属性的语法有着固定的格式,但是也有些灵活变化。
比如通过xml布局设置一个view的background color的几种方法:
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"
上面这些语法主要区别是对资源的访问和对样式属性的访问,详细可参考Android开发官网
引用资源(resources) 与 引用样式属性(style attribute) 的区别
@ 引用资源 (resources)
使用@语法引用资源时,是在访问一个实际的值(官网上标题使用 Accessing Resouces),这个资源必须有具体的值,我们能明确的知道自己使用的是哪个具体值。
比如定义了一个color资源:
.../values/color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#5F51B5</color/
</resources>
然后在xml中引用这个资源android:background="@color/colorPrimary",那么不管Activity是什么主题,background的值始终是确定值#5F51B5
? 引用样式属性 (style attribute)
使用?语法时,表示尝试引用一个样式属性(Referencing style attributes),具体的值取决于当前使用的主题。在特定的主题下,可以重写这个属性,因此不需要改变xml主题,只需要应用恰当的主题,background具体值就改变了。
<resource>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#F0A</item>
</style>
</resource>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?colorPrimary"
在这种情况下,我们询问Android:“嘿,把当前主题下定义的colorPrimary属性的值给我”。所以我们很难告诉你background到底会是什么颜色,因为它取决于这个布局所属的activity所应用的主题。
语法
引用资源 (@)
在xml中引用一个资源使用下面这个语法:
@[<package_name>:]<resource_type>/<resource_name>
-
<package_name>引用资源所在包的包名,** 如果在同一个包下引用,不是必须的; 使用android表示使用系统资源 ** -
<resource_type>R类的子集,即资源的类型(attr,color,string,dimen等等) -
<resource_name>资源名称,可以是不带后缀的资源文件名或者定义在xml中的资源
引用样式属性 (?)
?[<package_name>:][<resource_type>/]<resource_name>
引用样式属性语法和引用资源除了前缀是?,其他是一样的,其中<resource_type>/是个可选项,因为引用样式属性唯一的资源类型是attr,android打包工具允许我们省略资源类型。
所以从Android角度来看,下面的表述方式是完全一样的:
android:background="?com.myapp:attr/colorPrimary" // verbose format
android:background="?com.myapp:colorPrimary" // attr is skipped since its optional
android:background="?attr/colorPrimary" // package is skipped since its optional
android:background="?colorPrimary" // package & attr is skipped
引用系统样式属性:?android:colorPrimary