@android, ?attr/ 和 ?android 的区别
前言:安卓开发中我们时常会需要引用一些特殊的资源,比如设置一些可点击组件的波纹效果时,我们会用到:android:foreground=”?attr/selectableItemBackground”,但是这些引用方式之间有哪些区别呢?
获取资源
首先来复习一下安卓中获取资源的几种方式。
1 |
|
这种方式是最为常见的,直接获取对应的包下的资源,一般在相同的包下,可以省略包名,比如为 TextView 设置文字时,就可以通过这样的方式来获取我们应用内定义的 string 资源:
1 |
|
另一种获取资源的方式是通过引用 style
属性。
1 |
|
通过这种方式,我们可以获取到当前应用主题下的 style
属性值,这些属性值一般可以在属性文件夹 values
下找到。这里由于当前使用的是 Theme.AppCompat
下的主题,这是 com.android.support:appcompat-v7
下的 Theme,所以 colorAccent
会指向该库下的 values
文件:
关于资源引用的方式,具体请参考官方文档:Accessing your app resources
01 @android: 引用安卓内建的系统资源
除了引用自己应用中的资源外,我们还可以通过指定引用时的包名为 android
来获取安卓平台下的一些系统资源,举个例子:
1 |
|
我们知道当新建一个项目的时候,必须在 gradle 中设置 compileSdkVersion
来指定编译我们应用的 SDK 版本,这也决定了我们能调用哪个 level 的 API,同时也表明了哪个 level 的系统资源可供我们使用,比如如果指定的 compileSdkVersion
是 27,那么我们调用的就是 Android 8.1 下的系统资源。
02 ?attr/: 引用应用内的属性资源
通过这种方式可以让我们间接地使用应用内的某些资源。我们知道当我们自定义View的时候,一般会需要自定义一些属性资源,通常我们会在 values/
文件夹下建一个 attrs
文件,在这里保存一些我们自己的 style 属性,其实这些属性就可以通过 ?attr/
这种方式来引用了。比如我在 styles
里定义了一个属性:
1 |
|
定义完之后,我就可以直接在 layout
中通过引用的方式去使用这个属性了:
1 |
|
当然,要想让该属性起作用还需要在 Theme 下指定值:
另外,由于在 layout
中,可以自动识别出当前所需的是属性资源,所以可以省略 attr/
而直接使用 ?colorReallyGreen
就可以了。
03 ?android: 引用系统自带的属性资源
了解了前两种资源引用的方式后,?android
这种引用资源的方式也就不难理解了。与 ?attr/
类似,通过这种方式可以直接访问到安卓内建的属性资源,只不过是省略了 attr/
而已。比如给 TextView 引用一个系统内的 style buttonStyleSmall
:
1 |
|
然后 TextView 就变成了这样:
当然如果你尝试去掉 android
包名之后,发现该属性还是可以起作用,说明应用内也是可以引用这个资源的。那么这是不是意味着绝大部分属性资源都不需要加 android
包名呢?其实我觉得是这样的,因为加了包名之后其实限制反而会更多,比如有些内建属性资源是针对某个 API level 以上的 Android 平台才可以使用的,当然这也与你当前使用的 Theme 有关。
结语
总结下,获取资源有两种方式,一种是通过直接引用(使用 @
),一种是通过 style 属性(使用 ?
,除了自定义属性外,引用的资源类型和当前使用的主题有关)。另外,系统中内置了不少资源,学会合理利用它们可以帮助我们节约不少时间,建议大家花点精力自己探索下。