1 什麼是Resource
Resource,即資源,在Android中,資源是指代碼中使用附加文件和靜態內容,例如位圖、界面佈局、界面字符串、動畫說明等等。
我們將資源放在分類目錄下,以便單獨對其進行維護,例如圖像和代碼中的字符串。此外,還應爲特定設備提供備用資源,例如根據屏幕尺寸提供不同界面佈局,或者根據語言設置提供不同的字符串,
1.1 分組資源類型
各種類型的資源被放入項目res/
目錄的特定子目錄中。如下所示爲一個簡單項目的文件層次結構。
注意:切勿將資源文件直接保存在 res/ 目錄內,因爲這樣會造成編譯錯誤,應按類別新建子目錄。
MyProject/
src/
MyActivity.java
res/
drawable/
graphic.png
layout/
main.xml
info.xml
mipmap/
icon.png
values/
strings.xml
Android支持的分組資源類型請參考官方文檔:分組資源類型
1.2 提供備用資源
之所以提供備用資源,是爲了支持特定的設備配置。如針對不同的屏幕密度和語言,應分別加入備用的可繪製對象資源和備用字符串資源。在運行時,Android會檢測當前設備配置併爲應用加載合適的資源。
格式:在res/
目錄下創建以<resources_name>-<config_qualifier>
形式命名的新目錄
舉例:如下所示爲備用的可繪製對象資源:
更多有關可繪製對象資源類型請參考下圖:
更多配置限定符的內容請參考官方文檔提供備用資源,以及關於創建別名資源的方法請參考創建別名資源。
2 如何引用(訪問)Resource
編譯應用時,aapt會生成R類,其中包含res/目錄下所有資源的資源ID,每種資源類型都有對應的R子類,並且該類型下的每個資源都有靜態的整型數——資源ID。於是,我們可以在項目中藉助R
類中生成的資源ID來訪問這些資源。例如R.drawable對應於所有可繪製對象資源,引用方式爲R.drawable.icon。
2.1 在代碼中引用資源
格式:[<package_name>.]R.<resource_type>.<resource_name>
說明:
-
<package_name>
:是資源所在包的名稱,如果引用的資源是自己的提供的資源,則不需要; -
<resource_type>
:是資源類型的R
子類; -
<resource_name>
:是不帶擴展名的資源文件名。
注意資源名稱是不包含擴展名的,例如引用圖片時沒有必要加上.jpg
或者.png
等。
舉例:R.drawable.myimage
、R.string.main_title
、R.layout.main_screen
等。
2.2 在xml中引用資源-@
格式:@[<package_name>:]<resource_type>/<resource_name>
說明(同上):
-
<package_name>
:是資源所在包的名稱,如果引用的資源是自己的提供的資源,則不需要; -
<resource_type>
:是資源類型的R
子類; -
<resource_name>
:是不帶擴展名的資源文件名。
舉例:@color/opaque_red、@string/hello
如要引用系統資源,則您需要加入包名稱。例如:
android:textColor="@android:color/secondary_text_dark"
。由於系統資源分爲public和非public,public的聲明是在<sdk_path>\platforms\android-版本號\data\res\values\public.xml
,而@*
代表引用系統的非public資源。格式:
@*android:<resource_type>/<resource_name>
,可以調用系統定義的所有資源,而上面的
@android:<resource_type>/<resource_name>
,則只能夠調用public屬性的資源。
例如將 Android 提供的佈局資源用於 ListAdapter 中的列表項:setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));
,其中,simple_list_item_1
是平臺爲 ListView 中的項目所定義的佈局資源,即可以使用該資源,而不必自行創建列表項佈局。
2.3 引用樣式屬性-?
樣式屬性資源允許你在當前應用的主題中引用屬性的值。 引用樣式屬性,可以通過對UI元素進行樣式設置以匹配當前主題提供的標準變體來自定義UI元素的外觀,而不是提供硬編碼的值(即具體的值)。 引用樣式屬性本質上說:“在當前主題中使用此屬性定義的樣式。”
格式:?[<package_name>:][<resource_type>/]<resource_name>
舉例1,在xml文件中引用主題屬性:
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
<!-- Secondary text color. -->
<attr name="textColorSecondary" format="reference|color" />
在以上代碼中,是將android:textColor屬性指定爲當前主題背景中某個樣式屬性的名稱,即將android:textColorSecondary
樣式屬性的值用作此控件textColor
的值。
顯示聲明的格式爲:?android:attr/textColorSecondary
,但是這裏無須顯示聲明。
舉例2,在style文件中引用主題屬性:
<style name="Widget.CompoundButton">
<item name="focusable">true</item>
<item name="clickable">true</item>
<item name="textAppearance">?attr/textAppearance</item>
<item name="textColor">?attr/textColorPrimaryDisableOnly</item>
<item name="gravity">center_vertical|start</item>
</style>
2.4 訪問原始文件
若我們要訪問原始文件,則不應該將文件放於res/
目錄下,因爲從res/
讀取資源的唯一方法是使用資源 ID,因此,我們可以將資源保存在assets/
目錄中。
而訪問的方式則需要利用AssetManager讀取原始數據。如下所示
StringBuilder stringBuilder = new StringBuilder();
try {
AssetManager assetManager = context.getAssets();
BufferedReader bf = new BufferedReader(new InputStreamReader(
assetManager.open(file.json)));
String line;
while ((line = bf.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
但若是只需要讀取原始數據的能力,例如讀取視頻文件或音頻文件,則可將文件保存在res/raw/
目錄中,並利用openRawResource()
讀取字節流。如:mMediaPlayer = MediaPlayer.create(this, R.raw.song);
。
3 用 @+ 創建或引用資源
通過上面講解可以知道@
是引用的意思,那麼+
呢?+
表示在R.java
中名爲type的內部類中添加一條記錄。舉個例子:android:id="@+id/submit_btn"
表示新建一個名爲submit_btn
資源id。上面的例子就是最常見的用法,即定於控件id。
@+id/ID名稱
:表示新建一個資源ID;
@id/ID名稱
:引用已定義的資源ID,包括系統ID;
@android:id/ID名稱
:引用系統ID,其等效於@+id/ID名稱
。
4 根據資源名稱獲取資源ID
參考資料: