幾天前我偶然發現了我Android開發早期時製作的一份學習備忘單,是為理解如何處理Android資源和主題屬性的語法而整理的。
令人意外的是,我發現它對現在的我非常有用,因此決定整理成更適合部落格的形式並分享給大家。
知道我們今天要討論的話題了,那麼請看下面,通過xml佈局設定一個view的background color的幾種方法:
1 2 3 4 5 6 7 8 |
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" |
夠刺激,是吧?好吧,我希望可以把它拆解一下,這樣就可以不那麼嚇人了。
引用資源(resources) vs 引用樣式屬性(style attribute)
先打斷一下話題講一下Android的基礎,因為在進一步解釋之前,理解 @ 和 ? 之間的區別是很重要的。
當我們使用@ -我們是引用一個實際的值(color, string, dimension,等等)。這個資源必須有具體的值,這種情況下我們知道自己處理的具體值。
比如
app/src/main/res/values/color.xml
1 2 3 4 |
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> </resources> |
因此當我們想在xml中引用它的時候(android:background=”@color/colorPrimary”),不管這個activity是什麼主題的,background都將被設定為#3F51B5 。
反之,當你看到? 標記-那就意味著我們在嘗試引用一個style attribute ,其值取決於當前使用的主題。在特定的主題下我可以重寫這個屬性,因此不需要改變xml佈局,只需應用恰當的主題就是了:
1 2 3 4 5 |
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light"> <item name="colorPrimary">#F00</item> </style> </resources> |
1 2 3 4 5 |
<TextView android:id="@+id/my_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="?colorPrimary"/> |
在這種情況下,我們詢問Android:“嘿,把當前主題下定義的colorPrimary屬性的值給我”。所以我們很難告訴你background到底會是什麼顏色,因為它取決於這個佈局所屬的activity應用的主題。
語法
現在,讓我們來看看引用資源的語法到底是什麼樣的。
引用resources (@)
@[包名:]資源型別/資源名
- 包名 – 可選項,即這個資源所屬的包的名稱(預設就是你app的包名);預留的包-android,用於與系統一起釋出的資源。
- 資源型別 – R的子集,即資源的型別(attr, color, string, dimen,等等)
- 資源名 – 我們要引用的資源的名稱
讓我們先舉2個例子:
1 2 |
android:background="@color/colorPrimary" android:background="@com.myapp:color/colorPrimary" |
這兩個都是引用相同的資源,因為預設包名就是自己app的包名,所以可以不寫出來:
- package(可選) = com.myapp
- 資源型別 = color
- 資源名 = colorPrimary
你可能會想,安卓不是預先定義了一些系統級別的資源嗎?是的,比如可以這樣引用一些內建的顏色:
1 |
android:background="@android:color/holo_orange_dark" |
這個例子拆解開來就是:
- package = android – 引用內建的資源
- 資源型別 = color
- 資源名 = holo_orange_dark
請注意:
現在,許多開發者都使用AppCompat(如果你還沒有,那麼建議你這樣做),而AppCompat通常定義了自己的資源。雖然AppCompat屬於谷歌自己釋出的lib,但是它並不是系統的一部分。實際上,那些資源整合到了你的app中,因此不需要使用android關鍵字來引用。
例子:
1 |
android:background="?selectableItemBackground" |
這裡,即使我們app中並沒有自定義的屬性名selectableItemBackground(注意這裡沒有使用 android: 字首),我們仍然可以引用它,因為我們通過AppCompat把它“新增”到了我們的app中。
引用樣式屬性(?)
你猜怎麼著,它的語法相當類似於引用resources:
?[包名:][資源型別/]資源名稱
只是有點小區別:
引用樣式屬性的時候唯一允許的資源型別是attr。所以實際上Android打包工具允許我們省略資源型別,因此實際上它是一個可選項。
所以從Android的角度來看,下面的表述方式其實完全是一樣的:
1 2 3 4 |
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 |
就如你看到的那樣,其實語法是超級簡單的,再也不會困惑了!
相關文章: