@android, ?attr/ 和 ?android 的区别

作者: aJIEw | 来源:发表于2018-07-14 12:09 被阅读158次

    前言:安卓开发中我们时常会需要引用一些特殊的资源,比如设置一些可点击组件的波纹效果时,我们会用到:android:foreground="?attr/selectableItemBackground",但是这些引用方式之间有哪些区别呢?

    00 获取资源

    首先来复习一下安卓中获取资源的几种方式。

    @[<package_name>:]<resource_type>/<resource_name>
    

    这种方式是最为常见的,直接获取对应的包下的资源,一般在相同的包下,可以省略包名,比如为 TextView 设置文字时,就可以通过这样的方式来获取我们应用内定义的 string 资源:

    android:text="@string/hello"
    

    另一种获取资源的方式是通过引用 style 属性。

    android:textColor="?colorAccent"
    

    通过这种方式,我们可以获取到当前应用主题下的 style 属性值,这些属性值一般可以在属性文件夹 values 下找到。这里由于当前使用的是 Theme.AppCompat 下的主题,这是 com.android.support:appcompat-v7 下的 Theme,所以 colorAccent 会指向该库下的 values 文件:

    appcompat-v7 包下的 colorAccent 属性

    关于资源引用的方式,具体请参考官方文档:Accessing your app resources

    01 @android: 引用安卓内建的系统资源

    除了引用自己应用中的资源外,我们还可以通过指定引用时的包名为 android 来获取安卓平台下的一些系统资源,举个例子:

    android:background=“@android:drawable/ic_menu_delete”
    

    我们知道当新建一个项目的时候,必须在 gradle 中设置 compileSdkVersion 来指定编译我们应用的 SDK 版本,这也决定了我们能调用哪个 level 的 API,同时也表明了哪个 level 的系统资源可供我们使用,比如如果指定的 compileSdkVersion 是 27,那么我们调用的就是 Android 8.1 下的系统资源。

    @android:drawable/ic_menu_delete

    02 ?attr/: 引用应用内的属性资源

    通过这种方式可以让我们间接地使用应用内的某些资源。我们知道当我们自定义View的时候,一般会需要自定义一些属性资源,通常我们会在 values/ 文件夹下建一个 attrs 文件,在这里保存一些我们自己的 style 属性,其实这些属性就可以通过 ?attr/ 这种方式来引用了。比如我在 styles 里定义了一个属性:

    <attr name="colorReallyGreen" format="color"/>
    

    定义完之后,我就可以直接在 layout 中通过引用的方式去使用这个属性了:

    android:background="?attr/colorReallyGreen"
    

    当然,要想让该属性起作用还需要在 Theme 下指定值:

    在当前 Theme 下为自定义属性赋值

    另外,由于在 layout 中,可以自动识别出当前所需的是属性资源,所以可以省略 attr/ 而直接使用 ?colorReallyGreen 就可以了。

    03 ?android: 引用系统内建的属性资源

    了解了前两种资源引用的方式后,?android 这种引用资源的方式也就不难理解了。与 ?attr/ 类似,通过这种方式可以直接访问到安卓内建的属性资源,只不过是省略了 attr/ 而已。比如给 TextView 引用一个系统内的 style buttonStyleSmall

    <TextView
        style="?android:buttonStyleSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="You Are Beautiful" />
    

    然后 TextView 就变成了这样:

    引用了安卓内建属性作为 style 的 TextView

    当然如果你尝试去掉 android 包名之后,发现该属性还是可以起作用,说明应用内也是可以引用这个资源的。那么这是不是意味着绝大部分属性资源都不需要加 android 包名呢?其实我觉得是这样的,因为加了包名之后其实限制反而会更多,比如有些内建属性资源是针对某个 API level 以上的 Android 平台才可以使用的,当然这也与你当前使用的 Theme 有关。

    结语

    合理利用安卓内建资源其实可以节约我们很多时间,每一个安卓开发都应该花点时间探索下。


    参考:
    [1]: https://stackoverflow.com/questions/36642430/whats-the-difference-between-androidattr-and-attr-in-an-android-layout "What‘s the difference between “?android:attr/” and “?attr/” in an android layout xml file?"
    [2]: http://grishma102.blogspot.com/2015/02/difference-between-attr-and-androidattr.html "Difference between “?attr/” and “?android:attr/” in android"

    相关文章

      网友评论

      • sollian:原来“attr/”可以去掉,以前真不知道

      本文标题:@android, ?attr/ 和 ?android 的区别

      本文链接:https://www.haomeiwen.com/subject/agaepftx.html