@android, ?attr/ 和 ?android 的區別

前言:安卓開發中我們時常會需要引用一些特殊的資源,比如設置一些可點擊組件的波紋效果時,我們會用到:android:foreground="?attr/selectableItemBackground",但是這些引用方式之間有哪些區別呢?

獲取資源

首先來復習一下安卓中獲取資源的幾種方式。

@[<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 有關。

結語

總結下,獲取資源有兩種方式,一種是通過直接引用(使用 @),一種是通過 style 屬性(使用 ?,除了自定義屬性外,引用的資源類型和當前使用的主題有關)。另外系統中內置了不少資源,學會合理利用它們可以幫助我們節約不少時間,建議大家花點精力自己探索下。


參考:

  1. What‘s the difference between “?android:attr/” and “?attr/” in an android layout xml file?
  2. Difference between “?attr/” and “?android:attr/” in android
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。