資源是程式碼使用的額外檔案和靜態內容,例如點陣圖、版面配置定義、使用者介面字串和動畫指示等。
請一律將應用程式資源 (如圖片及字串) 與程式碼分開,以便個別維護這些資源。此外,請將替代資源歸類在已特別命名的資源目錄中,為特定裝置設定提供替代資源。Android 在執行階段中會根據目前設定使用合適的資源。舉例來說,您可能會想根據螢幕大小提供不同的 UI 版面配置,或是根據語言設定提供不同的字串。
將應用程式資源特別分開後,您便能使用在專案 R 類別中產生的資源 ID 存取這些資源。本文說明如何替 Android 專案中的資源分組,以及如何為特定裝置設定提供額外資源,然後透過應用程式程式碼或其他 XML 檔案存取這些資源。
群組資源類型
請在專案 res/ 目錄的特定子目錄中放入各類型的資源。下列為簡易專案的檔案階層範例:
MyProject/
src/
MyActivity.java
res/
drawable/
graphic.png
layout/
main.xml
info.xml
mipmap/
icon.png
values/
strings.xml
res/ 目錄包含子目錄中的所有資源:一個圖片資源、兩個版面配置資源、啟動器圖示的 mipmap/ 目錄,以及字串資源檔案。資源目錄名稱非常重要,表 1 將說明這些名稱。
表 1. 專案 res/ 目錄中支援的資源目錄。
目錄 |
資源類型 |
|
|
定義屬性動畫的 XML 檔案。 |
|
|
定義補間動畫的 XML 檔案。屬性動畫也可儲存在這個目錄中,但是最好放在 |
|
|
定義顏色狀態清單的 XML 檔案。詳情請參閱「顏色狀態清單資源」。 |
|
|
點陣圖檔案 (PNG、.
詳情請參閱「可繪製資源」。 |
|
|
適合不同啟動器圖示密度的可繪項目檔案。如要進一步瞭解如何使用 |
|
|
定義使用者介面版面配置的 XML 檔案。詳情請參閱「版面配置資源」。 |
|
|
定義應用程式選單 (例如選項選單、內容選單或子選單) 的 XML 檔案。詳情請參閱「選單資源」。 |
|
|
要以原始格式儲存的任意檔案。如要使用原始 不過,如果您需要存取原始檔案名稱和檔案階層,請考慮將資源儲存在 |
|
|
包含簡單值 (例如字串,整數以及顏色) 的 XML 檔案。 其他 因為每個資源是以自己的 XML 元素定義,所以您可以隨意命名檔案,也可以在一個檔案中放置不同的資源類型。不過,為求明確,建議您將不重複的資源類型放入不同的檔案中。舉例來說,以下是一些可以在此目錄中建立的資源檔案名稱慣例: |
|
|
可在執行階段中,藉由呼叫 |
|
|
有副檔名的字型檔案 (例如 TTF、OTF 或 TTC),或包含 |
凡是儲存在表格 1 所定義子目錄中的資源,就是您的預設資源。也就是說,這些資源可定義應用程式的預設設計和內容。不過,不同類型的 Android 裝置可能會呼叫不同類型的資源。
舉例來說,您可以為螢幕大小大於一般螢幕的裝置提供不同的版面配置資源,以便利用額外的螢幕空間。您也可以提供不同的字串資源,根據裝置的語言設定來翻譯使用者介面中的文字。除了預設資源外,您還需要提供額外資源,才能為不同的裝置設定提供不同的資源。
提供額外資源
大多數應用程式都會提供額外資源,用來支援特定的裝置設定,例如針對不同的螢幕密度和語言,分別提供額外可繪製資源和額外字串資源。Android 會在執行階段中偵測目前的裝置設定,並為您的應用程式載入合適的資源。

圖 1. 兩部裝置根據螢幕大小分別使用不同的版面配置資源。
如要為一組資源指定適用於特定設定的額外資源,請按照下列步驟操作:
在
res/中以<resources_name>-<qualifier>格式建立新目錄。- 「
<resources_name>」是對應預設資源的目錄名稱 (如表 1 定義)。 - 「
<qualifier>」是一個名稱,可指定要使用這些資源的個別設定 (如表 2 所示)。
您可以附加多個
<qualifier>。請使用破折號分隔。- 「
將相對應的額外資源儲存在這個新目錄中。資源檔案名稱必須與預設資源檔案名稱完全相同。
以下為一些預設以及額外資源範例:
res/
drawable/
icon.png
background.png
drawable-hdpi/
icon.png
background.png
hdpi 限定詞表示目錄中的資源適用於高密度螢幕裝置。這些可繪項目目錄中的圖片大小皆是針對特定螢幕密度設計,不過檔案名稱完全相同。如此一來,您在參照 icon.png 或 background.png 圖片時使用的資源 ID 就會一律相同。Android 會比較裝置設定資訊與資源目錄名稱中的限定詞,逐一選擇最符合目前裝置的資源版本。
表 2 按照優先順序列出了有效的設定限定詞。您可以在一個目錄名稱中加入多個限定詞,只要使用連字號分隔即可。如果資源目錄使用多個限定詞,您必須按照表中的次序將這些限定詞加進目錄名稱中。
表 2. 設定限定詞名稱。
設定 |
限定詞的值 |
說明 |
MCC 以及 MNC |
範例:
|
行動裝置國家/地區代碼 (MCC) 後面會選擇性加上裝置 SIM 卡上的行動網路識別碼 (MNC)。舉例來說, 如果裝置使用無線電連結功能 (GSM 手機),MCC 以及 MNC 的值會取自 SIM 卡。 您也可以單獨使用 MCC,例如在應用程式中加入特定國家/地區的法律資源時,就可以這麼做。如果只需要根據語言來指定,請改用「語言、指令碼 (選用) 和區域 (選用)」限定詞。如果您使用 MCC 和 MNC 限定詞,請小心留意,並測試是否能正常運作。 |
語言、指令碼 (選用) 和區域 (選用) |
範例:
|
語言是由兩個字母組成的 ISO 639-2{:.external} 語言代碼所定義,後面會選擇性加上兩個字母組成的 ISO 3166-1-alpha-2{:.external} 區碼 (前面加上小寫的 這些代碼「不」區分大小寫。 Android 7.0 (API 級別 24) 開始支援 BCP 47 語言標記{:.external},讓您可以限定特定語言和地區專屬的資源。語言標記是由一或多個子標記所組成,每個子標記都會修正或縮小整體標記識別的語言範圍。如要進一步瞭解語言標記,請參閱「語言辨識標記」{:.external}。 如要使用 BCP 47 語言標記,請串連 如果使用者在系統設定中變更語言,語言標記在應用程式的生命週期內可能會變更。如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。 如需將應用程式翻譯成其他語言的完整指南,請參閱「將應用程式本地化」。 另請參閱 |
| 語法性別 | masculinefeminineneuter |
使用者的語法性別。適用於有文法性別的語言。 舉例來說,如要為法語使用者提供不同資源,可以使用下列目錄:
請參閱 Android 中的「文法轉變」。 另請參閱 已加至 API 級別 34。 |
版面配置方向 |
|
應用程式的版面配置方向。 此設定適用於版面配置、可繪項目或值等任何資源。 舉例來說,如果要為阿拉伯文提供特定版面配置,其他「由右到左」的語言 (例如波斯文或希伯來文) 則提供一般版面配置,您可使用以下目錄:
注意:如要在應用程式中啟用由右至左的版面配置功能,您必須將 已新增至 API 等級 17。 |
最小寬度 |
範例:
其他 |
應用程式可用的螢幕區域最小尺寸。具體來說,應用程式視窗的 舉例來說,如果版面配置要求螢幕區域的最小尺寸一律至少須為 600 dp,您可以使用此限定詞在 使用最小寬度決定一般螢幕大小非常實用,因為寬度通常是設計版面配置時考量的因素。UI 通常是垂直捲動,但在水平方向所需的最小空間則有較嚴格的限制。 在決定要對手機採用單窗格版面配置,還是要對平板電腦採用多窗格版面配置時,可用寬度也是重要的考量因素,因此建議您留意各種裝置的最小寬度。 裝置的最小寬度會將螢幕裝飾和系統 UI 納入考量。舉例來說,如果裝置螢幕上有一些永久性的 UI 元素,會佔用最小寬度軸向的空間,系統宣告的最小寬度就會小於實際螢幕大小,因為這些元素是 UI 無法使用的螢幕像素。 以下是幾個您可能會在常見螢幕大小使用的值:
如果應用程式針對 已新增至 API 等級 13。 另請參閱 如要進一步瞭解如何在不同的螢幕設計使用此限定詞,請參閱「使用檢視區塊進行回應式/自動調整設計」。 |
可用的寬度和高度 |
範例:
其他 |
指定資源使用的最小可用螢幕寬度或高度 (以 可用的寬度和高度通常有助於決定是否要使用多窗格版面配置,因為即便在平板電腦裝置上,您通常也不需要針對直向螢幕方向,使用和橫向螢幕方向相同的多窗格版面配置。因此,您可以使用這些限定詞指定版面配置所需的最小寬度和/或高度,而不必同時使用螢幕大小和螢幕方向限定詞。 如果應用程式針對這些設定提供多個具有不同值的資源目錄,系統就會使用最接近 (但不超過) 裝置螢幕寬度的值。「最接近」是以在實際螢幕寬度和指定寬度之間的差距,加上實際螢幕高度和指定高度之間的差距來決定,未指定的高度和寬度值為 0。 這些值不包含視窗插邊佔用的區域,因此即使應用程式使用 這裡不會考量部分非固定的直向螢幕裝飾 (例如全螢幕時可隱藏的手機狀態列),也不會考量視窗裝飾 (例如標題列或動作列),因此應用程式必須準備好處理比指定空間略小的空間。 注意:系統會選擇寬度和高度皆相符的資源。因此,強烈建議您一併指定這兩種資源,不要僅指定其中一種資源。舉例來說,如果實際畫面的寬度為 720 dp,高度為 1280 dp,其中一個資源符合 w720dp 的條件,而另一個資源符合 w700dp-h1200dp 的條件,那麼即使前者與其指定的資源完全相符,系統仍會選擇後者。 已新增至 API 等級 13。 另請參閱 如要進一步瞭解如何在不同的螢幕設計使用此限定詞,請參閱「使用檢視區塊進行回應式/自動調整設計」。 |
螢幕大小 |
|
注意:使用大小限定詞不表示資源「只」適用於該大小的螢幕。如果您沒有為額外資源提供較符合目前裝置設定的限定詞,系統可能會使用任一最相符的資源。 注意:如果所有資源使用的大小限定詞均「大於」目前的螢幕畫面,則系統不會使用這些資源,而且應用程式會在執行階段中當機。舉例來說,當所有版面配置資源都加上 已新增至 API 級別 4。 另請參閱 詳情請參閱「螢幕相容性總覽」。 |
螢幕長寬比 |
|
已新增至 API 級別 4。 此設定僅以螢幕的顯示比例為依據 ( 另請參閱 |
圓形螢幕 |
|
已新增至 API 級別 23。 另請參閱 |
廣色域 |
|
已新增至 API 級別 26。 另請參閱 |
高動態範圍 (HDR) |
|
已新增至 API 級別 26。 另請參閱 |
螢幕方向 |
|
在應用程式生命週期內,這項設定會隨著使用者旋轉螢幕而改變。如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。 另請參閱 |
UI 模式 |
|
已加至 API 級別 8、API 級別 13 (電視)、API 級別 16 (家電)、API 級別 20 (手錶)、API 級別 26 (VR 頭戴式裝置)。 如需進一步瞭解裝置插入座架或從座架移除時,您的應用程式可以如何回應,請參閱「判斷及監控座架狀態/類型」。 在應用程式生命週期內,這項設定會在使用者將裝置插入座架時改變。你可以透過 |
夜間模式 |
|
已在 API 級別 8 中新增。 採用自動模式 (預設) 的夜間模式會因時間而切換,因此在應用程式生命週期內,這項設定會隨之變化。你可以使用 |
螢幕像素密度 (dpi) |
|
這六個主要像素的縮放密度比為 3:4:6:8:12:16 (不包括 tvdpi 密度),因此,ldpi 螢幕中的 9x9 點陣圖在 mdpi 中會是 12x12,在 hdpi 中會是 18x18,在 xhdpi 中會是 24x24,以此類推。 注意:使用像素密度限定詞並不表示資源「只」適用於該密度的螢幕。如果沒有為額外資源提供較符合目前裝置設定的限定詞,系統會使用任一最相符的資源。 如要進一步瞭解如何處理不同的螢幕密度,以及 Android 會如何縮放點陣圖來符合目前密度,請參閱「螢幕相容性總覽」。 |
觸控螢幕類型 |
|
另請參閱 |
可用鍵盤 |
|
如果您提供 在應用程式生命週期內,這項設定會因使用者開啟實體鍵盤而改變。如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。 另請參閱設定欄位 |
主要文字輸入法 |
|
另請參閱 |
可用瀏覽鍵 |
|
在應用程式生命週期內,如果使用者選擇顯示瀏覽鍵,這項設定就會隨之改變。如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。 另請參閱 |
主要非觸控瀏覽方式 |
|
另請參閱 |
平台版本 (API 級別) |
範例:
其他 |
裝置支援的 API 級別。例如, |
限定詞名稱規則
以下是一些關於使用設定限定詞名稱的規則:
- 您可以為一組資源指定多個限定詞,只要用連字號隔開即可。舉例來說,
drawable-en-rUS-land適用於螢幕方向為橫向的美式英文裝置。 - 限定詞必須按照表 2 的順序排列。
- 錯誤:
drawable-hdpi-port/ - 正確:
drawable-port-hdpi/
- 錯誤:
- 不得建立巢狀額外資源目錄。例如,您不能使用
res/drawable/drawable-en/。 - 值不區分大小寫。資源編譯器進行處理前會將目錄名稱轉換為小寫,避免不區分大小寫的檔案系統發生問題。名稱中的任何大寫字母僅是為辨識更加容易。
- 每一種限定詞只支援一個值。舉例來說,如要針對西班牙和法國使用相同的可繪項目檔案,您就「不能」將目錄命名為
drawable-es-fr/,而是需要建立包含相應檔案的兩個資源目錄,例如drawable-es/和drawable-fr/。不過,您不需要真的在這兩個位置複製檔案,可以改為按照「建立別名資源」一節的說明,為資源建立「別名」。
將額外資源存入名稱含這些限定詞的目錄後,Android 會根據目前的裝置設定,自動在應用程式中套用資源。每次要求資源時,Android 會查看包含所要求資源檔案的額外資源目錄,找出最相符的資源。
如果沒有額外資源符合該裝置設定,Android 會使用對應的預設資源,亦即一組不包含設定限定詞的特定類型資源。
建立別名資源
如果您想將某一資源用於多種裝置設定上,但不想以預設資源的方式提供,並不需要在多個額外資源目錄中放入同一個資源。而是可以改為建立一個額外資源,做為預設資源目錄中所存資源的別名。
舉例來說,假設您有應用程式圖示 icon.png,且需要針對不同的語言代碼提供專屬版本。但有兩個語言代碼需要使用相同的版本,分別是英文 (加拿大) 以及法文 (加拿大)。您不需要將相同圖片一併複製到英文 (加拿大) 及法文 (加拿大) 的資源目錄,而是可以將這兩種語言使用的圖片儲存為 icon.png「以外」的任意名稱 (例如 icon_ca.png),然後放入預設的 res/drawable/ 目錄中。接著,只要在 res/drawable-en-rCA/ 和 res/drawable-fr-rCA/ 中建立 icon.xml 檔案,藉此使用 <bitmap> 元素參照 icon_ca.png 資源,就可以只儲存一種版本的 PNG 檔案,以及指向該 PNG 檔案的兩個 XML 小檔案。詳情請參閱下節中的範例。
可繪項目
如要建立現有可繪項目的別名,請使用 <drawable> 元素。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="icon">@drawable/icon_ca</drawable>
</resources>
如果將此檔案儲存為 icon.xml 並放入額外資源目錄 (例如 res/values-en-rCA/) 中,系統會將其編譯成可做為 R.drawable.icon 參照的資源,但它實際上是儲存在 res/drawable/ 中的 R.drawable.icon_ca 資源的別名。
版面配置
如要建立現有版面配置的別名,請使用在 <merge> 之中納入的 <include> 元素:
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="@layout/main_ltr"/>
</merge>
如果將此檔案儲存為 main.xml,系統會將檔案編譯為可做 R.layout.main 參照的資源,但實際上是 R.layout.main_ltr 資源的別名。
存取應用程式資源
在應用程式中提供資源後,您就可以參照資源 ID 來套用資源。所有資源 ID 都會在專案的 R 類別中定義,然後自動產生 aapt 工具。
當您編譯應用程式時,aapt 會產生 R 類別,其中包含 res/ 目錄中所有資源的資源 ID。每個資源類型都有 R 子類別,例如可繪製資源全都有 R.drawable。而該類型的每種資源都有靜態整數,例如 R.drawable.icon。此整數是資源 ID,可用來擷取資源。
雖然 R 類別是指定資源 ID 的位置,但您不需要在此尋找資源 ID。資源 ID 一律由下列項目組成:
- 「資源類型」:每個資源都會以「類型」分組,例如
string, drawable和layout。如要進一步瞭解不同的類型,請參閱「資源類型總覽」。 - 「資源名稱」,這可以是檔案名稱 (不含副檔名),或是資源
android:name屬性中的簡單值 (例如:字串)。
存取資源的方式有兩種:
- 在程式碼中:從
R類別的子類別中,使用靜態整數,例如:R.string.hellostring是資源類型,hello是資源名稱。當您以此格式提供資源 ID 時,會有很多 Android API 可以存取您的資源。詳情請參閱「在程式碼中存取資源」一節。 - 在 XML 中:使用與
R類別中定義的資源 ID 對應的特殊 XML 語法,例如:@string/hello。string是資源類型,hello則是資源名稱。您可以在 XML 資源中任何需要您提供值的位置使用此語法。詳情請參閱「從 XML 存取資源」一節。
在程式碼中存取資源
您可以傳遞資源 ID 做為方法參數,這樣就能在程式碼中使用資源。舉例來說,您可以使用 setImageResource,將 ImageView 設定為使用 res/drawable/myimage.png 資源:
Kotlin
val imageView = findViewById(R.id.myimageview) as ImageView
imageView.setImageResource(R.drawable.myimage)
Java
ImageView imageView = (ImageView) findViewById(R.id.myimageview);
imageView.setImageResource(R.drawable.myimage);
您也可以使用 Resources 中的方法 (使用 getResources 取得執行個體) 擷取個別資源。
語法
以下是在程式碼中參照資源的語法:
[<package_name>.]R.<resource_type>.<resource_name>
<package_name>是資源所在的套件名稱 (參照套件中的資源時不需要)。<resource_type>是資源類型的R子類別。- 「
<resource_name>」是不含副檔名的資源檔案名稱,如果是簡單值,則也可以是 XML 元素中的android:name屬性值。
用途
許多方法都接受使用資源 ID 參數,而且您可以使用 Resources 中的方法擷取資源。您可以使用 Context.getResources 取得 Resources 的例項。
以下是一些在程式碼中存取資源的範例:
Kotlin
// Load a background for the current screen from a drawable resource.
window.setBackgroundDrawableResource(R.drawable.my_background_image)
// Set the Activity title by getting a string from the Resources object, because
// this method requires a CharSequence rather than a resource ID.
window.setTitle(resources.getText(R.string.main_title))
// Load a custom layout for the current screen.
setContentView(R.layout.main_screen)
// Set a slide in animation by getting an Animation from the Resources object.
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.hyperspace_in))
// Set the text on a TextView object using a resource ID.
val msgTextView = findViewById(R.id.msg) as TextView
msgTextView.setText(R.string.hello_message)
Java
// Load a background for the current screen from a drawable resource.
getWindow().setBackgroundDrawableResource(R.drawable.my_background_image) ;
// Set the Activity title by getting a string from the Resources object, because
// this method requires a CharSequence rather than a resource ID.
getWindow().setTitle(getResources().getText(R.string.main_title));
// Load a custom layout for the current screen.
setContentView(R.layout.main_screen);
// Set a slide in animation by getting an Animation from the Resources object.
flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.hyperspace_in));
// Set the text on a TextView object using a resource ID.
TextView msgTextView = (TextView) findViewById(R.id.msg);
msgTextView.setText(R.string.hello_message);
從 XML 存取資源
您可以使用現有資源的參照,定義某些 XML 屬性和元素的值。通常您必須在建立版面配置檔案時執行此操作,才能為小工具提供字串和圖片。
舉例來說,如果您在版面配置中加入 Button,請針對按鈕文字使用字串資源:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/submit" />
語法
以下是在 XML 資源中參照資源的語法:
@[<package_name>:]<resource_type>/<resource_name>
<package_name>是資源所在的套件名稱 (如果參照的資源是來自相同套件則不需要)。<resource_type>是資源類型的R子類別。- 「
<resource_name>」是不含副檔名的資源檔案名稱,如果是簡單值,則也可以是 XML 元素中的android:name屬性值。
用途
在某些情況下,您必須在 XML 中針對單一值使用資源 (例如,將可繪項目圖片套用至小工具),但您也可以在 XML 中接受簡單值的任何位置使用資源。舉例來說,如果您有以下資源檔案,且這些資源檔案包含顏色資源和字串資源:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="opaque_red">#f00</color>
<string name="hello">Hello!</string>
</resources>
您可以在下列版面配置檔案中使用這些資源,設定文字顏色和文字字串:
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@color/opaque_red"
android:text="@string/hello" />
在這種情況下,您不需要在資源參照中指定套件名稱,因為資源來自於您自己的套件。如要參照系統資源,您需加入套件名稱,如以下範例所示:
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="@android:color/secondary_text_dark"
android:text="@string/hello" />
您甚至可以使用 XML 中的資源以建立別名。舉例來說,您可以建立可繪製資源,做為另一個可繪製資源的別名:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/other_drawable" />
雖然這聽起來很多餘,但在使用額外資源時卻相當實用。詳情請參閱「建立別名資源」一節。
參照樣式屬性
樣式屬性資源可讓您參照目前所套用主題中的屬性值。參照樣式屬性後,您就可以設定 UI 元素的樣式,讓其外觀符合目前主題提供的標準變化版本,藉此自訂 UI 元素的外觀,而非提供硬式編碼的值。參照樣式屬性基本上也就是「在目前的主題中,使用這個屬性定義的樣式」。
如要參照樣式屬性,名稱語法會跟一般資源格式幾乎相同,但會以問號 (?) 取代 @ 符號 (@),而資源類型部分為選用。因此,參考語法會像下面這樣:
?[<package_name>:][<resource_type>/]<resource_name>
舉例來說,以下說明如何參照屬性,以設定與系統主題的次要文字顏色相符的文字顏色:
<EditText id="text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:text="@string/hello_world" />
這裡的 android:textColor 屬性會指定目前主題中的樣式屬性名稱。Android 現在會使用套用至 android:textColorSecondary 樣式屬性的值,做為這個小工具中的 android:textColor 值。由於系統資源工具知道此結構定義中預期會有屬性資源,因此您不需要明確指出類型,也就是 ?android:attr/textColorSecondary。您可以排除 attr 類型。
存取原始檔案
在少數情況下,您可能需要存取原始檔案和目錄。如要執行這類操作,檔案並不合適儲存在 res/ 中,原因在於從 res/ 讀取資源的唯一方法是使用資源 ID。因此,您可以改為將資源儲存在 assets/ 目錄中。
儲存在 assets/ 目錄中的檔案「沒有」資源 ID,因此您無法透過 R 類別或 XML 資源參照這些檔案。您可以改為像一般檔案系統一樣查詢 assets/ 目錄中的檔案,然後使用 AssetManager 讀取原始資料。
不過,如果您只是要讀取原始資料 (例如:影片或音訊檔案),請將檔案儲存在 res/raw/ 目錄中,然後使用 openRawResource 讀取位元組串流。
存取平台資源
Android 包含多個標準資源,例如樣式、主題和版面配置。如要存取這些資源,請使用 android 套件名稱界定資源參照。舉例來說,您可以將 Android 提供的版面配置資源用於 ListAdapter 中的清單項目:
Kotlin
listAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, myarray)
Java
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myarray));
在這個範例中,simple_list_item_1 是由平台針對 ListView 中的項目定義的版面配置資源。您可以改用此方法,不必自己建立清單項目的版面配置。
利用資源提供最佳裝置相容性
為了讓應用程式可以支援多種裝置設定,請務必一律為應用程式所用的資源逐一提供預設資源。
舉例來說,如果應用程式支援多種語言,請一律提供「不含」語言和地區限定詞的 values/ 目錄 (用於儲存字串)。反之,如果您是將所有字串檔案放在帶有語言及地區限定詞的目錄中,且裝置設為字串所不支援的語言,應用程式在該裝置執行時就會當機。
只要您提供預設的 values/ 資源,即便使用者不懂系統顯示的語言,應用程式也會正常運作。這樣總比應用程式當機要好。
同理,如果您根據不同螢幕方向提供不同的版面配置資源,請挑選一種螢幕方向做為預設方向。舉例來說,您不需要在 layout-land/ 和 layout-port/ 中各別提供橫向和直向版面配置資源,只要保留其一做為預設即可,例如:橫向為 layout/,直向為 layout-port/。
提供預設資源非常重要,這不僅是因為應用程式可能會在您預期之外的設定中執行,也是因為新版本的 Android 有時會加入舊版不支援的設定限定詞所致。如果您使用新的資源限定詞,但代碼仍與舊版 Android 相容,舊版 Android 就無法使用以新限定詞命名的資源,因此在沒有預設資源的情況下執行應用程式就會當機。
舉例來說,如果 minSdkVersion 設為 4,且限定所有可繪製資源使用夜間模式 (night 或 notnight,已加至 API 級別 8),API 級別 4 裝置便無法存取可繪製資源,且會造成當機。在這種情況下,您可能會想使用 notnight 做為預設資源,因此請排除該限定詞,並將可繪製資源放入 drawable/ 或 drawable-night/ 中。
簡言之,為了提供最佳的裝置相容性,請一律提供預設資源,讓應用程式具備順利執行所需的資源。接著使用設定限定詞,針對特定的裝置設定建立額外資源。
這項規則有一例外狀況,如果應用程式的 minSdkVersion 為 4 以上,當您使用螢幕密度限定詞提供額外可繪製資源時,「不需要」提供預設的可繪製資源。即使沒有預設的可繪製資源,Android 依然可以在額外螢幕密度中找到最相符的資源,並在必要時調整點陣圖大小。不過,為了讓所有裝置類型的使用者都能享有最佳體驗,三種螢幕密度都應該提供額外可繪項目。