天天看點

閑談Android中的@和?符号的引用差別

閑談Android中的@和?符号的引用差別

在 android 項目開發中,我們經常會用 “@” 或者 “?” 符号去引用系統或者我們應用内添加的資源,這兩種符号的引用有什麼差別呢,“?attr/” 與 “?android:attr/” 之間又有怎樣的不同呢?本文我們不妨閑聊一下。

“@” 與 “?” 符号的引用在使用時都有一個規範的格式:"@[+][package:]type:name","?[package:][type:]name"。可以看到,二者均包含引用符号、資源所屬的包、資源類型和資源名稱。

@ 資源引用

“@” 符号用于引用系統和我們在項目中添加的一些固有資源(drawable,string 等),或者定義的 style 樣式。比如:

android:text="@string/app_name" 

這裡的 app_name 就是我們自己定義在項目檔案 values/strings.xml 中的字元串資源。

android:text="@android:string/cancel" 

而這裡的 cancel 屬于 android sdk 中的系統字元串資源,是以需要添加@android: 來指明引用來源。android: 是 package: 的一個具體執行個體。

? 屬性引用

“?” 符号用于引用目前主題中定義的一些屬性值。注意,“?” 符号通過屬性名字間接引用目前主題中的對應屬性值,而不是屬性本身。舉個例子:

android:divider="?android:listdivider" 

這裡的 “?” 符号通過屬性名 android:listdivider 間接擷取目前主題賦予該屬性的值。如同 @android: 一般,?android: 表示該值源自 android sdk 系統屬性。由于在目前主題中尋找對應屬性名的值,是以沒有指定屬性類型,其實等同于:?android:attr/listdivider。

那如何引用項目中自定義的屬性呢?我們在 attrs.xml 中定義一個屬性,如:

<declare-styleable name="customtextview"> 

    <attr name="colortextcustom" format="reference|color"/> 

</declare-styleable> 

顯然,此時我們定義的 colortextcustom 屬性是沒有值的,直接引用沒有任何作用。需要在主題 style 中指派:

<style name="basetheme" parent="theme.appcompat.light.noactionbar"> 

    <item name="colortextcustom">#ff0000</item> 

</style> 

<style name="apptheme" parent="basetheme"> 

    <item name="android:textcolor">?colortextcustom</item> 

可以看到,這裡在 basetheme 中對 colortextcustom 屬性指派,并在 apptheme 中通過 “?colortextcustom” 引用該屬性值。由于是本地項目中定義的屬性,是以沒有添加 android: 命名空間。其實,這種做法的好處是,apptheme 所覆寫的 view 均可通過構造函數擷取目前主題中的 colortextcustom 屬性值。

r.attr & r.style

android sdk 中定義有很多屬性和主題可供使用,詳見官方文檔:r.attr &r.style。使用系統資源的好處就是,滿足不同系統的适配需求,較為靈活。

這裡舉幾個常用的:

style="?android:attr/borderlessbuttonstyle"

android 5.0 預設 button 的樣式自帶邊框陰影,可以使用這個系統樣式去除該樣式。當然,這是單獨設定時的操作,為了友善全局控制,可以在 styles.xml 中自定義一個樣式,繼承一個無邊框樣式作為 parent:

<style name="customborderlessbuttonstyle" parent="@style/widget.appcompat.button.borderless"> 

    <item name="android:textcolor">@android:color/white</item> 

    ... 

android:background="?android:attr/selectableitembackground"

可用于設定一些 list item、button之類帶點選效果的背景。該樣式自帶觸摸點選效果,在 5.0 和更高版本上,更是附有 ripple 漣漪效果,省去我們自己實作 selector 選擇器的過程。當然我們也可以自己使用 <ripple> 标簽定義一個 drawable 檔案實作漣漪效果,隻是需要注意版本限制。

android:background="?android:attr/dividervertical"

實作分割線背景。

還有一些其他有用的系統資源,這裡就不一一列舉了...

作者:亦楓

來源:51cto