Android資源與屬性備忘單
幾天前我偶然發現了我Android開發早期時制作的一份學習備忘單,是為理解如何處理Android資源和主題屬性的語法而整理的。
令人意外的是,我發現它對現在的我非常有用,因此決定整理成更適合博客的形式并分享給大家。
知道我們今天要討論的話題了,那么請看下面,通過xml布局設置一個view的background color的幾種方法:
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
<?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布局,只需應用恰當的主題就是了:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">#F00</item>
</style>
</resources>
<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個例子:
android:background="@color/colorPrimary"
android:background="@com.myapp:color/colorPrimary"
這兩個都是引用相同的資源,因為默認包名就是自己app的包名,所以可以不寫出來:
-
package(可選) = com.myapp
-
資源類型 = color
-
資源名 = colorPrimary
你可能會想,安卓不是預先定義了一些系統級別的資源嗎?是的,比如可以這樣引用一些內置的顏色:
android:background="@android:color/holo_orange_dark"
這個例子拆解開來就是:
-
package = android - 引用內置的資源
-
資源類型 = color
-
資源名 = holo_orange_dark
請注意:
現在,許多開發者都使用AppCompat(如果你還沒有,那么建議你這樣做),而AppCompat通常定義了自己的資源。雖然AppCompat屬于谷歌自己發布的lib,但是它并不是系統的一部分。實際上,那些資源整合到了你的app中,因此不需要使用android關鍵字來引用。
例子:
android:background="?selectableItemBackground"
這里,即使我們app中并沒有自定義的屬性名selectableItemBackground(注意這里沒有使用 android: 前綴),我們仍然可以引用它,因為我們通過AppCompat把它“添加”到了我們的app中。
引用樣式屬性(?)
你猜怎么著,它的語法相當類似于引用resources:
?[包名:][資源類型/]資源名稱
只是有點小區別:
引用樣式屬性的時候唯一允許的資源類型是attr。所以實際上Android打包工具允許我們省略資源類型,因此實際上它是一個可選項。
所以從Android的角度來看,下面的表述方式其實完全是一樣的:
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
就如你看到的那樣,其實語法是超級簡單的,再也不會困惑了!
來自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/0324/7720.html