應用程式資源總覽

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

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

Android 支援多個設定限定詞,因此您可以在一個目錄名稱中加入多個限定詞,只要使用連字號個別分開即可。表 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 中新增。

smallestWidth sw<N>dp

範例:
sw320dp
sw600dp
sw720dp
等。

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

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

使用最小寬度決定一般螢幕大小,因為寬度通常是設計版面配置時考量的因素。UI 常會垂直捲動,但水平方向的最小所需空間則相當受限。在決定要使用手機的單面板版面配置和平板電腦的多面板版面配置時,可用寬度也是重要因素,因此建議您留意各種裝置的最小寬度。

裝置的 smallestWidth 已將畫面裝飾以及系統 UI 列入考量。舉例來說,如果裝置本身有固定的 UI 元素,而這些元素佔用 smallestWidth 軸線旁的空間時,系統顯示的 smallestWidth 會小於實際畫面大小,因為這些畫面像素不包含在 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(boolean)WindowCompat#setDecorFitsSystemWindows(Window,boolean) 顯示邊到邊,寬度和高度的值也會小於實際畫面尺寸。

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

注意:系統會選擇寬度和高度皆相符的資源。因此,兩種都指定的資源都會比僅指定一種的資源要來得好。舉例來說,如果實際畫面是 h720dp x h1280dp,有一個資源符合使用 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 中新增。

僅以螢幕的長寬比為根據 (「長型」螢幕較寬),這與螢幕方向無關。

另請參閱 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:裝置在電視上顯示,提供所謂的「10 英尺」使用體驗,也就是顯示 UI 的大型螢幕與使用者距離遙遠,主要使用方向鍵或其他非指標互動的方式進行操作
  • 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) 螢幕,約 160dpi。
  • hdpi:高密度螢幕,約 240 dpi
  • xhdpi:超高密度螢幕,約 320dpi。已在 API 級別 8 中新增
  • xxhdpi:超超高密度螢幕,約 480dpi。已在 API 級別 16 中新增
  • xxxhdpi:特別超高密度螢幕 (僅限啟動器圖示,請參閱「支援多螢幕」中的附註),約 640dpi。已在 API 級別 18 中新增
  • nodpi:如果您不希望點陣圖資源為配合密度縮放,此限定詞就可以在這些點陣圖資源中使用。
  • tvdpi:介於 mdpi 與 hdpi 之間的螢幕,約 213dpi。這並不是「主要的」像素密度分組,主要用於電視,且大多數應用程式均不需要使用此限定詞。已在 API 級別 13 中新增
  • anydpi:此限定詞與所有螢幕密度相符,且優先順序高於其他限定詞。對於向量可繪項目而言,這很實用。已在 API 級別 21 中新增
  • nnndpi:用於表示非標準密度,其中 nnn 是正整數螢幕密度。在大部分情況下,我們都不建議使用這個項目。使用標準密度級別,即可大幅降低市面上各種裝置螢幕密度的負擔。

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

如果您認為圖片資源在電視或某些裝置上看起來效果不夠好而想嘗試使用 tvdpi 資源,縮放比例係數為 1.33*mdpi。例如,mdpi 螢幕的 100px x 100px 圖片在 tvdpi 螢幕上應為 133px x 133px。

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

如需進一步瞭解如何處理不同螢幕密度,以及 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 1.0 版開始就已加入,所以並不是所有版本的 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_ca.png (icon.png 以外的任何名稱),然後放入預設的 res/drawable/ 目錄中。然後在 res/drawable-en-rCA/res/drawable-fr-rCA/ 中建立 icon.xml 檔案,藉此使用 <bitmap> 元素參照 icon_ca.png 資源。如此一來,您只要儲存一種版本的 PNG 檔案,以及指向該 PNG 檔案的兩個 XML 小檔案即可 (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,但實際上這是 R.drawable.icon_ca資源的別名 (儲存在 res/drawable/ 中)。

版面配置

如要建立現有版面配置的別名,請使用在 <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。如要進一步瞭解不同的類型,請參閱「資源類型」。
  • 「資源名稱」,這可以是檔案名稱 (不含副檔名),或是資源 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 元素的外觀,而非提供硬式編碼值。參照樣式屬性基本上就是「在目前的主題中,使用這個屬性定義的樣式」。

如要參照樣式屬性,名稱語法與一般資源格式幾乎相同,但不會使用 @ 符號 (@),而是使用問號 (?),且資源類型部分為選擇性。例如:

?[<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

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

根據螢幕大小限定詞選擇資源時,如果沒有其他更符合的資源,系統會使用為較小螢幕設計的資源 (例如,一個大螢幕在必要時會使用一般大小螢幕資源)。不過,如果唯一的可用資源比目前螢幕「大」,系統就不會使用這些資源。假如沒有其他資源符合裝置設定,應用程式還會當機。舉例來說,如果所有版面配置資源都是以 xlarge 限定詞標記,但裝置使用一般大小螢幕,就會發生上述情況。

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