應用程式資源總覽

資源是程式碼使用的額外檔案和靜態內容,例如點陣圖、版面配置定義、使用者介面字串和動畫指示等。

請務必將應用程式資源 (如圖片及字串) 從程式碼外部化,以便個別維護這些資源。您應該要將替代資源歸類在特別命名的資源目錄中,為特定裝置設定提供替代資源。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 將說明這些名稱。

注意:如需進一步瞭解如何使用 mipmap 資料夾,請參閱「將應用程式圖示放在 mipmap 目錄中」。

表 1 專案 res/ 目錄中支援的資源目錄。

目錄 資源類型
animator/ 定義屬性動畫的 XML 檔案。
anim/ 定義補間動畫的 XML 檔案。屬性動畫也可儲存在這個目錄中,但是屬性動畫最好放在 animator/ 目錄,以便區分這兩種不同類型的動畫。
color/ 定義顏色狀態清單的 XML 檔案。詳情請參閱「色彩狀態清單資源」。
drawable/

點陣圖檔案 (PNG、.9.png、JPG 或 GIF) 或編譯為以下可繪製資源子類型的 XML 檔案:

  • 點陣圖檔案
  • Nine-Patch (可調整大小的點陣圖)
  • 狀態清單
  • 形狀
  • 動畫可繪項目
  • 其他可繪項目

詳情請參閱「可繪製資源」。

mipmap/ 適合不同啟動器圖示密度的可繪項目檔案。如要進一步瞭解如何使用 mipmap/ 資料夾管理啟動器圖示,請參閱「將應用程式圖示放在 mipmap 目錄中」。
layout/ 定義使用者介面版面配置的 XML 檔案。詳情請參閱「版面配置資源」。
menu/ 定義應用程式選單的 XML 檔案,例如選項選單、內容選單或子選單。詳情請參閱「選單資源」。
raw/

要以原始格式儲存的任意檔案。如要使用原始 InputStream 開啟這些資源,請使用資源 ID (R.raw.filename) 呼叫 Resources.openRawResource()

不過,如果您需要存取原始檔案名稱和檔案階層,請考慮將資源儲存在 assets/ 目錄中,而非 res/raw/assets/ 中的檔案並未提供資源 ID,因此您只能使用 AssetManager 讀取。

values/

包含簡單值 (例如字串,整數以及顏色) 的 XML 檔案。

其他 res/ 子目錄中的 XML 資源檔案會根據 XML 檔案名稱定義單一資源,而 values/ 目錄中的檔案則是描述多個資源。對於在此目錄中的檔案而言,<resources> 元素的每個子項只會定義一個資源。舉例來說,<string> 元素會建立 R.string 資源,而 <color> 元素則會建立 R.color 資源。

因為每個資源是以自己的 XML 元素定義,所以您可以隨意命名檔案,也可以在一個檔案中放置不同的資源類型。不過,為求明確,您可能會想將不重複的資源類型放在不同檔案中。舉例來說,以下是一些可以在此目錄中建立的資源檔案名稱常見慣例:

詳情請參閱字串資源樣式資源更多資源類型

xml/ 執行階段中呼叫 Resources.getXML() 可讀取的任意 XML 檔案。各種 XML 設定檔都必須儲存在這裡,例如搜尋設定
font/ 有副檔名的 TTF、OTF 或 TTC 等字型檔案,或包含 <font-family> 元素的 XML 檔案。如要進一步瞭解如何將字型做為資源,請參閱「將字型新增為 XML 資源」。

注意:請勿直接在 res/ 目錄中儲存資源檔案,這會導致編譯器發生錯誤。

如要進一步瞭解個別資源類型,請參閱「資源類型總覽」。

儲存在表格 1 已定義子目錄中的資源,是您的預設資源,也就是說,這些資源定義應用程式的預設設計和內容。不過,不同類型的 Android 裝置可能會呼叫不同類型的資源。

舉例來說,您可以為尺寸大於一般螢幕的裝置提供不同的版面配置資源,以便充分運用額外的螢幕空間。您也可以提供不同的字串資源,根據裝置的語言設定來翻譯使用者介面中的文字。除了預設資源外,您還需要提供額外資源,才能為不同的裝置設定提供不同的資源。

提供額外資源

大多數應用程式都會提供額外資源,用來支援特定的裝置設定。例如,提供支援不同螢幕密度的額外可繪製資源,以及支援不同語言的額外字串資源。Android 會在執行階段中偵測目前的裝置設定,並為您的應用程式載入合適的資源。

圖 1 兩部裝置根據螢幕大小分別使用不同的版面配置資源。

如果要為一組資源指定特別設定的替代資源,請依照以下步驟操作:

  1. res/ 中以 <resources_name>-<qualifier> 格式建立新目錄。
    • <resources_name>是對應預設資源的目錄名稱 (如表 1 定義)。
    • <qualifier>是一個名稱,可指定要使用這些資源的個別設定 (如表 2 所示)。

    您可以附加多個「<qualifier>。請使用破折號分隔。

    注意:附加多個限定詞時,您必須按照表 2 的順序排列這些限定詞。如果限定詞的順序錯誤,系統就會忽略資源。

  2. 將相對應的額外資源儲存在這個新目錄中。資源檔案名稱必須與預設資源檔案名稱完全相同。

以下為一些預設以及額外資源範例:

res/
    drawable/
        icon.png
        background.png
    drawable-hdpi/
        icon.png
        background.png

hdpi 限定詞表示目錄中的資源是在高密度螢幕裝置使用。這些可繪項目目錄中的圖片大小皆針對特定螢幕密度設計,不過檔案名稱完全相同。如此一來,您在參照 icon.pngbackground.png 圖片使用的資源 ID 就會相同。Android 會比較裝置設定資訊與資源目錄名稱中的限定詞,選擇最符合目前裝置的每個資源版本。

注意:定義額外資源時,請務必也在預設設定中定義資源。否則,裝置變更設定時,應用程式可能會發生執行階段例外狀況。舉例來說,如果只新增字串至 values-en,而非 values,那麼當使用者變更預設的系統語言時,應用程式可能會發生 Resource Not Found 例外狀況。

表 2 按照優先順序列出有效的設定限定詞。您可以在一個目錄名稱中加入多個限定詞,只要使用連字號分隔即可。如果資源目錄使用多個限定詞,您必須按照表格中的次序將這些限定詞加入目錄名稱。

表 2. 設定限定詞名稱

設定 限定詞的值 說明
MCC 和 MNC 範例:
mcc310
mcc310-mnc004
mcc208-mnc00

行動裝置國家/地區代碼 (MCC) 後面會選擇性加上裝置 SIM 卡上的行動裝置網路代碼 (MNC)。舉例來說,mcc310 代表美國的任何電信業者,mcc310-mnc004 是美國 Verizon,mcc208-mnc00 則是法國的 Orange。

如果裝置使用無線電連結功能 (GSM 手機),MCC 以及 MNC 的值會來自 SIM 卡。

您也可以單獨使用 MCC,例如在應用程式中加入特定國家/地區的法律資源。如果只需要根據語言指定,請改用「語言、指令碼 (選用) 和區域 (選用)」限定詞。如果您使用 MCC 和 MNC 限定詞,請謹慎並測試運作是否正常。

另請參閱 mcc 以及 mnc 設定欄位,這兩個欄位分別顯示目前的行動裝置國家代碼以及行動裝置網路代碼。

語言、指令碼 (選用) 和區域 (選用) 例如:
en
fr
en-rUS
fr-rFR
fr-rCA
b+en
b+en+US
b+es+419
b+zh+Hant
b+sr+Latn+RS

語言是由兩個字母組成的 ISO 639-1 語言代碼所定義,後面會選擇性加上兩個字母組成的 ISO 3166-1-alpha-2 區碼 (前面加上小寫的 r)。

這些代碼「不」區分大小寫r 前置字串是用於區分區碼。您無法單獨指定地區。

Android 7.0 (API 級別 24) 加入了對 BCP 47 語言標記的支援,讓您可以限定特定語言以及地區專屬的資源。語言標記是由一或多個子標記所組成,每個子標記都會修正或縮小整體標記識別的語言範圍。如要進一步瞭解語言標記,請參閱「語言辨識標記」。

如要使用 BCP 47 語言標記,請串連 b+ 和兩個字母的 ISO 639-1 語言程式碼,後面可選擇性使用 + 分隔的其他子標記。

如果使用者在系統設定中變更語言,在應用程式的生命週期內可能會變更語言標記。如果想進一步瞭解這麼做在執行階段期間對應用程式有何影響,請參閱「處理設定變更」。

如需將應用程式翻譯成其他語言的完整指南,請參閱「將應用程式本地化」。

另請參閱 getLocales() 方法,取得已定義的語言代碼清單。此清單包含主要的語言代碼。

版面配置方向 ldrtl
ldltr

應用程式的版面配置方向。ldrtl 表示「layout-direction-right-to-left」(版面配置方向由右至左)。ldltr 表示「layout-direction-left-to-right」(版面配置方向由左到右),這個值為預設的隱含值。

適用於任何資源,例如版面配置、可繪項目或值。

例如,如果要為阿拉伯文提供特定版面配置,其他「由右到左」的語言 (例如波斯文或希伯來文) 則提供一般版面配置,可以使用以下目錄:

res/
  layout/
    main.xml (預設版面配置)
  layout-ar/
    main.xml (阿拉伯文的特定版面配置)
  layout-ldrtl/
    main.xml (從右到左的語言,但阿拉伯文除外,因為「ar」語言限定詞的優先順序較高)

注意:如要在應用程式中啟用由右至左的版面配置,您必須將 SupportsRtl 設定為 "true",然後將 TargetSdkVersion 設定為 17 以上。

已在 API 級別 17 中新增。

最小寬度 sw<N>dp

範例:
sw320dp
sw600dp
sw720dp
等。

應用程式可用的螢幕區域最小尺寸。具體來說,應用程式視窗的 smallestWidth 是指視窗可用的最短高度和寬度。您也可以將其視為視窗「最小的可能寬度」。您可以使用此限定詞,確保應用程式提供的 UI 寬度至少為 <N> dp。

舉例來說,如果版面配置要求螢幕區域的最小尺寸至少須為 600 dp,您可以使用此限定詞在 res/layout-sw600dp/ 目錄中建立版面配置資源。無論可用畫面的最小尺寸對使用者來說是高度或寬度,只有在該尺寸至少為 600 dp 時,系統才會使用這些資源。如果調整視窗大小 (變更可用寬度/高度) 或重新調整位置 (可能會改變系統插邊),最小寬度可能會改變。

使用最小寬度決定一般螢幕大小,因為寬度通常是設計版面配置時考量的因素。UI 通常是垂直捲動,但它在水平方向所需的最小空間則有較嚴格的限制。

在決定要對手機採用單窗格版面配置,還是要對平板電腦採用多窗格版面配置時,可用寬度也是重要的考量因素,因此建議您留意各種裝置的最小寬度。

裝置的最小寬度會將螢幕裝飾和系統 UI 納入考量。舉例來說,如果裝置的螢幕畫面上有永久性的 UI 元素會沿著最小寬度軸佔用空間,則系統會宣告最小寬度小於實際螢幕大小,因為這些元素是您的使用者介面中無法使用的螢幕像素。

以下是幾個您可能會在常見螢幕大小使用的值:

  • 320,適用於有螢幕設定的裝置,例如:
    • 240x320 ldpi (QVGA 手機)
    • 320x480 mdpi (手機)
    • 480x800 hdpi (高密度手機)
  • 480,適用於 480x800 mdpi 這類的螢幕 (平板電腦/手機)
  • 600,適用於 600x1024 mdpi 這類螢幕 (7 吋平版電腦)
  • 720,適用於 720x1280 mdpi 這類的螢幕 (10 吋平板電腦)

如果應用程式針對 smallestWidth 限定詞提供多個具有不同值的資源目錄,系統會使用最接近 (但不超過) 裝置 smallestWidth 的值。

已在 API 級別 13 中新增。

另請參閱 android:requiresSmallestWidthDp 屬性,這可宣告與應用程式相容的最小 smallestWidth 以及 smallestScreenWidthDp 設定欄位,後者會保留裝置的 smallestWidth 值。

如要進一步瞭解如何在不同的螢幕設計使用此限定詞,請參閱「支援不同的螢幕大小」。

可用的寬度和高度 w<N>dp
h<N>dp

範例:
w720dp
w1024dp
h720dp
h1024dp
等。

指定資源使用的最小可用螢幕寬度或高度 (以 <N> 值定義的 dp 單位)。當裝置螢幕方向在直向和橫向、裝置折疊或展開,或是系統進入或退出多視窗模式之間變更,這些設定值會與目前螢幕寬度和高度進行比較。在多視窗模式中,這些值反映包含應用程式的視窗寬度和高度,而非裝置螢幕的寬度和高度。同樣的,如果是嵌入活動,這些值會與個別活動的寬度和高度有關,而不是螢幕的寬度和高度。詳情請參閱「活動嵌入」。

可用的寬度和高度通常有助於決定是否要使用多窗格版面配置,因為即便在平板電腦裝置上,您通常也不需要針對直向螢幕方向,使用和橫向螢幕方向相同的多窗格版面配置。因此,您可以使用此限定詞指定版面配置所需的最小寬度和/或高度,而不必同時使用螢幕大小和螢幕方向限定詞。

如果應用程式針對這些設定提供多個具有不同值的資源目錄,系統就會使用最接近 (但不超過) 裝置螢幕寬度的目錄。最接近,是以實際螢幕寬度和指定寬度之間的差距,加上實際螢幕高度和指定高度之間的差距,再加上未指定高度及值為 0 的寬度來決定。

這些值不含由視窗插邊所佔的區域,因此,如果裝置在螢幕邊緣有永久性的 UI 元素,則寬度和高度的值就會小於實際螢幕尺寸,即使應用程式是透過 Window.setDecorFitsSystemWindows WindowCompat.setDecorFitsSystemWindows 顯示為邊緣也一樣。

部分未修正的垂直螢幕裝飾 (例如可以在全螢幕中隱藏的手機狀態列) 並「不」在此列,視窗裝飾 (例如標題列或動作列) 也不在此列,因此應用程式必須做好準備,才能處理比指定範圍稍小的空間。

注意:系統會選擇寬度和高度皆相符的資源。因此,強烈建議您一併指定這兩種資源,不要僅指定其中一種資源。舉例來說,如果實際畫面的寬度為 720 dp,高度為 1280 dp,其中一個資源符合 w720dp 的條件,而另一個資源符合 w700dp-h1200dp 的條件,那麼即使前者與其指定的資源完全相符,系統仍會選擇後者。

已在 API 級別 13 中新增。

另請參閱 screenWidthDpscreenHeightDp 設定欄位,這些欄位會保留目前的螢幕寬度和高度。

如要進一步瞭解如何在不同的螢幕設計使用此限定詞,請參閱「支援不同的螢幕大小」。

螢幕大小 small
normal
large
xlarge
  • small:與低密度 QVGA 螢幕大小相似的螢幕。小型螢幕的版面配置大小最小值約為 320x426 dp 單位,例如 QVGA 低密度以及 VGA 高密度螢幕。
  • normal:與中密度 HVGA 螢幕大小相似的螢幕。中型螢幕的版面配置大小最小值約為 320x470 dp 單位,例如 WQVGA 低密度、HVGA 中密度以及 WVGA 高密度螢幕。
  • large:與中密度 VGA 螢幕大小相似的螢幕。大型螢幕的版面配置大小最小值約為 480x640 dp 單位,例如 VGA 以及 WVGA 中密度螢幕。
  • xlarge:明顯大於傳統中密度 HVGA 螢幕的螢幕。超大型螢幕的版面配置大小最小值約為 720x960 dp 單位。大多數情況下,超大型螢幕裝置通常為平板裝置,且不方便隨身攜帶。已在 API 級別 9 中新增。

注意:使用大小限定詞不表示資源「只」適用於該大小的螢幕。如果未提供含有較符合目前裝置設定的限定詞額外資源,系統可能會使用任何最相符的資源。

注意:如果所有資源使用的大小限定詞「大於」目前的螢幕畫面,則系統不會使用這些資源,而且應用程式會在執行階段中當機。舉例來說,當所有版面配置資源都加上 xlarge 限定詞標記,但裝置使用一般尺寸螢幕,就會發生這種情況。

已在 API 級別 4 中新增。

另請參閱 screenLayout 設定欄位,此欄位會顯示螢幕為小型、中型或大型。

詳情請參閱「螢幕相容性總覽」。

螢幕長寬比 long
notlong
  • long:長型螢幕,例如 WQVGA、WVGA 以及 FWVGA。
  • notlong:非長型螢幕,例如 QVGA、HVGA 以及 VGA。

已在 API 級別 4 中新增。

此設定僅以螢幕的長寬比為依據 (long 螢幕較寬)。這與螢幕方向無關。

另請參閱 screenLayout 設定欄位,此欄位會顯示螢幕是否為長型。

圓形螢幕 round
notround
  • round:圓形螢幕,例如圓形的穿戴式裝置
  • notround:矩形螢幕,例如手機或平板電腦

已在 API 級別 23 中新增。

另請參閱 isScreenRound() 設定方法,此方法會顯示螢幕是否為圓形。

廣色域 widecg
nowidecg
  • widecg:採用廣色域的螢幕,例如 Display P3 或 AdobeRGB
  • nowidecg:採用窄色域的螢幕,例如 sRGB

已在 API 級別 26 中新增。

另請參閱 isScreenWideColorGamut() 設定方法,此方法會指出螢幕是否具有廣色域。

高動態範圍 (HDR) highdr
lowdr
  • highdr:採用高動態範圍的螢幕
  • lowdr:採用低/標準動態範圍的螢幕

已在 API 級別 26 中新增。

另請參閱 isScreenHdr() 設定方法,此方法會顯示螢幕是否具有 HDR 功能。

螢幕方向 port
land
  • port:裝置螢幕方向為縱向 (垂直)
  • land:裝置螢幕方向為橫向 (水平)

在應用程式效期內,這會隨著使用者旋轉螢幕而改變。如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。

另請參閱 orientation 設定欄位,此欄位表示目前的裝置螢幕方向。

UI 模式 car
desk
television
appliance
watch
vrheadset
  • car:裝置正在車用座架中顯示
  • desk:裝置正在桌面座架中顯示
  • television:裝置在電視上顯示,提供所謂的「十英尺」使用體驗,也就是顯示 UI 的大型螢幕與使用者距離遙遠,主要使用 D-Pad 或其他非指標互動進行操作
  • appliance:裝置沒有螢幕,僅做為設備使用
  • watch:裝置有螢幕,並戴在手腕上
  • vrheadset:裝置在虛擬實境耳機中顯示螢幕

已在 API 級別 8 中新增;電視已在 API 級別 13 中新增;手錶已在 API 級別 20 中新增。

如需進一步瞭解裝置插入座架或從座架移除時,您的應用程式可以如何回應,請參閱「判斷與監控座架狀態/類型」。

在應用程式生命週期內,這個值會在使用者將裝置插入座架時改變。您可以透過 UiModeManager 啟用或停用部分模式。如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。

夜間模式 night
notnight
  • night:夜間
  • notnight:白天

已在 API 級別 8 中新增。

停留在自動模式 (預設) 的夜間模式會隨著時間切換,因此在應用程式效期內該限定詞的值會隨著模式切換而改變。您可以透過 UiModeManager 啟用或停用夜間模式。 如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。

螢幕像素密度 (dpi) ldpi
mdpi
hdpi
xhdpi
xxhdpi
xxxhdpi
nodpi
tvdpi
anydpi
nnndpi
  • ldpi:低密度螢幕,約 120 dpi。
  • mdpi:中密度 (傳統 HVGA) 螢幕,約 160 dpi。
  • hdpi:高密度螢幕,約 240 dpi。
  • xhdpi:超高密度螢幕,約 320 dpi。已在 API 級別 8 中新增。
  • xxhdpi:超超高密度螢幕,約 480 dpi。已在 API 級別 16 中新增。
  • xxxhdpi:特別超高密度螢幕 (僅限啟動器圖示,請參閱「支援不同的像素密度」);約 640 dpi。已新增至 API 等級 18。
  • nodpi:如果您不希望點陣圖資源配合裝置密度縮放,可以使用這個限定詞。
  • tvdpi:密度介於 mdpi 與 hdpi 之間的螢幕,約 213dpi。 這並不是「主要的」像素密度分組,主要用於 720p 的電視,且大多數應用程式不需要使用此限定詞。果是 1080p 電視面板,請使用 xhdpi;如果是 4K 電視面板,請使用 xxxhdpi。已在 API 級別 13 中新增。
  • anydpi:與所有螢幕密度相符,且優先順序高於其他限定詞。對於向量可繪項目而言,這很實用。已在 API 級別 21 中新增。
  • nnndpi:用於表示非標準密度,其中 nnn 是正整數螢幕密度。在大部分情況下用不到此限定詞。使用標準密度級別可大幅降低市面上各種裝置螢幕密度的負擔。

六個主要像素的縮放密度比為 3:4:6:8:12:16 (不包括 tvdpi 密度),所以,ldpi 螢幕中的 9x9 點陣圖在 mdpi 中會是 12x12,在 hdpi 中會是 18x18,在 xhdpi 中會是 24x24,以此類推。

注意:使用密度限定詞並不表示資源「只」適用於該密度的螢幕。如未提供含有較符合目前裝置設定的限定詞額外資源,系統可能會使用任何最相符的資源。

如要進一步瞭解如何處理不同的螢幕密度,以及 Android 會如何調整點陣圖比例以符合目前密度,請參閱「螢幕相容性總覽」。

觸控螢幕類型 notouch
finger
  • notouch:裝置沒有觸控螢幕。
  • finger:裝置有觸控螢幕,透過使用者手指的互動方向操作。

另請參閱 touchscreen 設定欄位,此欄位表示裝置的觸控螢幕類型。

可用鍵盤 keysexposed
keyshidden
keyssoft
  • keysexposed:裝置有可用鍵盤。如果裝置啟用了螢幕鍵盤 (這點很有可能),在使用者「沒有」看到實體鍵盤或裝置本身沒有實體鍵盤的情況下,可能還是會使用此限定詞。如果螢幕鍵盤沒有提供或是已停用,只有在使用者看到實體鍵盤時才會使用這個限定詞。
  • keyshidden:裝置有可用實體鍵盤但已隱藏,「而且」裝置「沒有」啟用螢幕鍵盤。
  • keyssoft:裝置已啟用螢幕鍵盤 (不論顯示與否)。

如果提供 keysexposed 資源,但未提供 keyssoft 資源,只要系統已啟用螢幕鍵盤,系統就會使用 keysexposed 資源,不論鍵盤是否可見。

在應用程式效期內,該限定詞的值會因使用者開啟實體鍵盤而改變。如要進一步瞭解這在執行階段中對應用程式有何影響,請參閱「處理設定變更」。

另請參閱設定欄位 hardKeyboardHiddenkeyboardHidden,其中分別顯示實體鍵盤的瀏覽權限,以及任何鍵盤類型 (包括螢幕鍵盤) 的瀏覽權限。

主要文字輸入法 nokeys
qwerty
12key
  • nokeys:裝置沒有實體鍵盤可輸入文字。
  • qwerty:裝置有實體 QWERTY 鍵盤 (不論是否有向使用者顯示)。
  • 12key:裝置有實體 12 鍵鍵盤 (不論是否有向使用者顯示)。

另請參閱 keyboard 設定欄位,此欄位表示可用的主要文字輸入法。

平台版本 (API 級別) 範例:
v3
v4
v7
等。

裝置支援的 API 級別。例如,v1 表示 API 級別 1 (使用 Android 1.0 以上版本的裝置),v4 表示 API 級別 4 (使用 Android 1.6 以上版本的裝置)。如要進一步瞭解這些值,請參閱 Android API 級別說明文件。

注意:並非所有 Android 版本皆支援所有限定詞。使用新限定詞會間接新增平台版本限定詞,因此舊版裝置可以忽略新限定詞。舉例來說,使用 w600dp 限定詞會自動加入 v13 限定詞,因為可用寬度限定詞在 API 級別 13 中為新屬性。為避免發生問題,請務必加入一組預設資源 (一組「不含限定詞」的資源)。詳情請參閱「利用資源提供最佳裝置相容性」一節。

限定詞名稱規則

以下是一些關於使用設定限定詞名稱的規則:

  • 您可以為一組資源指定多個限定詞,只要用連字號隔開即可。舉例來說,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 會使用對應的預設資源 (為不包含設定限定詞類型而設的一組資源)。

建立別名資源

如果要在多個裝置設定中使用相同的資源,但不想以預設資源提供,您不需要在多個額外資源目錄中放入相同的資源。相對的,可以改為建立一個替代資源,這個替代資源為某個資源的別名,並儲存於您的預設資源目錄。

注意:並非所有資源都提供可為另一個資源建立別名的機制。具體來說,xml/ 目錄中的動畫、選單、原始和其他未指定的資源都不會提供此功能。

舉例來說,假設您有應用程式圖示 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 做為新字串的值使用。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello</string>
    <string name="hi">@string/hello</string>
</resources>

R.string.hi 資源現在是 R.string.hello 的別名。

其他簡單值的運作方式亦同,例如顏色:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="red">#f00</color>
    <color name="highlight">@color/red</color>
</resources>

存取應用程式資源

在應用程式中提供資源後,您就可以參照資源 ID 以進行套用。所有資源 ID 都會在專案的 R 類別中定義,然後自動產生 aapt 工具。

編譯應用程式時,aapt 會產生 R 類別,其中包含 res/ 目錄中所有資源的資源 ID。每個資源類型都有 R 子類別,例如所有可繪製資源的 R.drawable。該類型的每種資源都有靜態整數,例如 R.drawable.icon。此整數是資源 ID,可用來擷取資源。

雖然 R 類別是指定資源 ID 的位置,但您不需要在此尋找資源 ID。資源 ID 一律由下列項目組成:

  • 資源類型:每個資源都會以「類型」分組,例如 stringdrawablelayout。如要進一步瞭解不同的類型,請參閱「資源類型總覽」。
  • 資源名稱:不含副檔名的檔案名稱,如果資源是簡單值 (例如字串),則也可以是 XML android:name 屬性中的值。

存取資源的方式有兩種:

  • 在程式碼中:使用 R 類別子類別中的靜態整數,例如:
    R.string.hello

    string 是資源類型,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);

注意:請勿手動修改 R.java 檔案,因為這是編譯專案時由 aapt 工具產生。任何變更都會在您下次編譯時覆寫。

從 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 元素的外觀,而非提供硬式編碼的值。參照樣式屬性基本上也就是「在目前的主題中,使用這個屬性定義的樣式」。

如要參照樣式屬性,名稱語法與一般資源格式幾乎相同,但請勿使用「at」符號 (@),而是使用問號 (?)。資源類型部分為選用項目。因此,參考語法如下:

?[<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,且限定所有可繪製資源使用夜間模式 (nightnotnight,在 API 級別 8 中新增),API 級別 4 裝置便無法存取可繪製資源,且會造成當機。在這種情況下,您可能想要使用 notnight 做為預設資源,因此請排除該限定詞,並將可繪製資源放入 drawable/drawable-night/ 中。

簡言之,為了提供最佳的裝置相容性,請務必提供預設資源,讓應用程式具備順利執行所需的資源。接著使用設定限定詞,針對特定的裝置設定建立額外資源。

以下為例外情況:如果應用程式的 minSdkVersion 為 4 以上,則使用螢幕密度限定詞提供額外可繪製資源時「不需要」預設可繪製資源。即使沒有預設的可繪製資源,Android 依然可以在額外螢幕密度中找到最相符的資源,並在必要時調整點陣圖大小。然而,為了讓所有裝置類型的使用者都能享有最佳體驗,三種螢幕密度都應該提供替代可繪項目。

Android 如何尋找最相符的資源

當您要求資源以提供額外資源時,Android 會根據目前的裝置設定要在執行階段使用的額外資源。以下範例示範 Android 如何選擇額外資源;假設下列可繪項目目錄各包含不同版本的相同圖片:

drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/

並假設下列為該裝置的設定:

語言代碼 = en-GB
螢幕方向 = port
螢幕像素密度 = hdpi
觸控螢幕類型 = notouch
主要文字輸入法 = 12key

比較裝置設定與可用額外資源後,Android 會從 drawable-en-port 選擇可繪項目。

然後系統會決定要使用的資源,邏輯如下:

圖 2. Android 找出最相符資源的流程圖。

  1. 排除與裝置設定相牴觸的資源檔案。

    drawable-fr-rCA/ 目錄排除,因為與 en-GB 語言代碼牴觸。

    drawable/
    drawable-en/
    drawable-fr-rCA/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    例外:螢幕像素密度是唯一不會因牴觸而排除的限定詞。即使裝置的螢幕密度為 hdpi,drawable-port-ldpi/ 也不會排除,而這是因為目前每個螢幕密度都會視為相符。詳情請參閱「螢幕相容性總覽」。

  2. 選出清單 (表 2) 中優先順序最 (次) 高的限定詞(從 MCC 開始)。
  3. 有任何資源包含此限定詞嗎?
    • 如果沒有,請回到步驟 2 查看下一個限定詞。在此範例中,語言限定詞以前的答案皆為「沒有」。
    • 如果有,請前往步驟 4。
  4. 排除不包含此限定詞的資源目錄。在此範例中,系統接下來會排除所有不包含語言限定詞的目錄:
    drawable/
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    drawable-port-ldpi/
    drawable-port-notouch-12key/
    

    例外:如果上述的限定詞為螢幕像素密度,Android 會選擇最接近該裝置螢幕密度的選項。一般來說,比起放大較小原圖,Android 偏好縮小較大原圖。詳情請參閱「螢幕相容性總覽」。

  5. 重複步驟 2、3 和 4,直到僅剩一個目錄為止。在此範例中,螢幕方向為下一個有相符項目的限定詞,因此,沒有指定螢幕方向的資源會遭到排除:
    drawable-en/
    drawable-en-port/
    drawable-en-notouch-12key/
    

    剩餘的目錄是 drawable-en-port

雖然系統會對每個要求的資源執行此流程,不過仍會對某些部分進行最佳化。其中一項最佳化是在知道裝置設定後,可能會排除永遠不會相符的額外資源。舉例來說,如果設定語言為「英文」,任何將語言限定詞設為「英文」以外語言的資源目錄就永遠不會納入已檢查資源集區中 (但「不含」語言限定詞的資源目錄仍會在此集區中)。

根據螢幕大小限定詞選擇資源時,如果沒有其他更符合的資源,系統會使用為較小螢幕設計的資源。例如,大型螢幕在必要時使用一般大小螢幕資源。

不過,如果唯一可用資源比目前的畫面「大於」,則系統不會使用這些資源,且如果沒有其他資源符合裝置設定,應用程式就會當機。舉例來說,如果所有版面配置資源都加上 xlarge 限定詞標記,但裝置是一般尺寸螢幕,就會發生這種情況。

注意:限定詞的「優先順序」(表 2) 比與裝置完全相符的限定詞數量還更重要。在上述範例中,步驟 4 中的最後一個選項包含三個完全符合裝置的限定詞 (螢幕方向、觸控螢幕類型以及輸入法),而 drawable-en 只有一個參數符合 (語言)。不過,由於語言的優先順序高於這些限定詞,因此系統會排除 drawable-port-notouch-12key