天天看點

android 應用基礎知識(2)---應用資源Android資源

Android資源

  您應該始終外部化應用資源,例如圖像和代碼中的字元串,這樣有利于您單獨維護這些資源。 此外,您還應該為特定裝置配置提供備用資源,方法是将它們分組到專門命名的資源目錄中。 在運作時,Android 會根據目前配置使用适當的資源。例如,您可能需要根據螢幕尺寸提供不同的 UI 布局,或者根據語言設定提供不同的字元串。

外部化應用資源後,即可使用在項目 

R

 類中生成的資源 ID 通路這些資源。有關如何在應用中使用資源,我們将在通路資源中讨論。 本文檔介紹如何對 Android 項目中的資源進行分組,以及如何為特定的裝置配置提供備用資源。

分組資源類型

您應将各種資源放入項目 

res/

 目錄的特定子目錄下。例如,以下是一個簡單項目的檔案層次結構:

MyProject/ src/ MyActivity.java res/ drawable/ graphic.png layout/ main.xml info.xml mipmap/ icon.png values/ strings.xml

正如您在此示例中所看到的那樣,

res/

 目錄包含所有資源(在子目錄下):一個圖像資源、兩個布局資源、啟動器圖示的 

mipmap/

 目錄以及一個字元串資源檔案。資源目錄名稱非常重要,将在表 1 中進行介紹。

注:如需了解有關使用 mipmap 檔案夾的詳細資訊,請參閱管理項目概覽。

表 1. 項目 

res/

 目錄内支援的資源目錄。

目錄 資源類型

animator/

用于定義屬性動畫的 XML 檔案。

anim/

定義漸變動畫的 XML 檔案。(屬性動畫也可以儲存在此目錄中,但是為了區分這兩種類型,屬性動畫首選 

animator/

 目錄。)

color/

用于定義顔色狀态清單的 XML 檔案。請參閱顔色狀态清單資源

drawable/

位圖檔案(

.png

.9.png

.jpg

.gif

)或編譯為以下可繪制對象資源子類型的 XML 檔案:
  • 位圖檔案
  • 九宮格(可調整大小的位圖)
  • 狀态清單
  • 形狀
  • 動畫可繪制對象
  • 其他可繪制對象
請參閱 可繪制對象資源。

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 元素定義,是以您可以根據自己的需要命名檔案,并将不同的資源類型放在一個檔案中。但是,為了清晰起見,您可能需要将獨特的資源類型放在不同的檔案中。 例如,對于可在此目錄中建立的資源,下面給出了相應的檔案名約定:

  • arrays.xml,用于資源數組(類型化數組)。
  • colors.xml:顔色值。
  • dimens.xml:尺寸值。
  • strings.xml:字元串值。
  • styles.xml:樣式。
請參閱字元串資源、樣式資源和更多資源類型。

xml/

可以在運作時通過調用 

Resources.getXML()

 讀取的任意 XML 檔案。各種 XML 配置檔案(如可搜尋配置)都必須儲存在此處。

注意:切勿将資源檔案直接儲存在 

res/

 目錄内,這會導緻出現編譯錯誤。

如需了解有關某些資源類型的詳細資訊,請參閱資源類型文檔。

儲存在表 1 中定義的子目錄下的資源是“預設”資源。即,這些資源定義應用的預設設計和内容。但是,采用 Android 技術的不同裝置類型可能需要不同類型的資源。例如,如果裝置的螢幕尺寸大于标準螢幕,則應提供不同的布局資源,以充分利用額外的螢幕空間。 或者,如果裝置的語言設定不同,則應提供不同的字元串資源,以轉換使用者界面中的文本。 要為不同的裝置配置提供這些不同資源,除了預設資源以外,您還需要提供備用資源。

提供備用資源

android 應用基礎知識(2)---應用資源Android資源

圖 1. 兩種不同的裝置,均使用不同的布局資源。

幾乎每個應用都應提供備用資源以支援特定的裝置配置。 例如,對于不同的螢幕密度和語言,您應分别包括備用可繪制對象資源和備用字元串資源。 在運作時,Android 會檢測目前裝置配置并為應用加載合适的資源。

為一組資源指定特定于配置的備用資源:

  1. 在 

    res/

     中建立一個以 

    <resources_name>-<config_qualifier>

     形式命名的新目錄。
    • <resources_name>

       是相應預設資源的目錄名稱(如表 1 中所定義)。
    • <qualifier>

       是指定要使用這些資源的各個配置的名稱(如表 2 中所定義)。
    您可以追加多個 

    <qualifier>

    。以短劃線将其分隔。

    注意:追加多個限定符時,必須按照表 2 中列出的相同順序放置它們。如果限定符的順序錯誤,則該資源将被忽略。

  2. 将相應的備用資源儲存在此新目錄下。這些資源檔案的名稱必須與預設資源檔案完全一樣。

例如,以下是一些預設資源和備用資源:

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

hdpi

 限定符表示該目錄中的資源适用于螢幕密度較高的裝置。其中每個可繪制對象目錄中的圖像已針對特定的螢幕密度調整大小,但是檔案名完全相同。 這樣一來,用于引用 

icon.png

 或 

background.png

 圖像的資源 ID 始終相同,但是 Android 會通過将裝置配置資訊與資源目錄名稱中的限定符進行比較,選擇最符合目前裝置的各個資源版本。

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

等等
語言通過由兩個字母組成的 ISO 639-1 語言代碼定義,可以選擇後跟兩個字母組成的 ISO 3166-1-alpha-2 區域碼(前帶小寫字母“

r

”)。

這些代碼不區分大小寫;

r

 字首用于區分區域碼。 不能單獨指定區域。

如果使用者更改系統設定中的語言,它有可能在應用生命周期中發生改變。 如需了解這會在運作期間給應用帶來哪些影響,請參閱處理運作時變更。

有關針對其他語言本地化應用的完整指南,請參閱本地化。

另請參閱 

locale

 配置字段,該字段表示目前的語言區域。
布局方向

ldrtl

ldltr

應用的布局方向。

ldrtl

 是指“布局方向從右到左”。

ldltr

 是指“布局方向從左到右”,這是預設的隐式值。

它适用于布局、圖檔或值等任何資源。

例如,若要針對阿拉伯語提供某種特定布局,并針對任何其他“從右到左”語言(如波斯語或希伯來語)提供某種通用布局,則可編碼如下:

res/ layout/ main.xml (Default layout) layout-ar/ main.xml (Specific layout for Arabic) layout-ldrtl/ main.xml (Any "right-to-left" language, except for Arabic, because the "ar" language qualifier has a higher precedence.)

注:要為應用啟用從右到左的布局功能,必須将 

supportsRtl

 設定為 

"true"

,并将 

targetSdkVersion

 設定為 17 或更高版本。

此項為 API 級别 17 中新增配置。

smallestWidth

sw<N>dp

示例:

sw320dp

sw600dp

sw720dp

等等
螢幕的基本尺寸,由可用螢幕區域的最小尺寸指定。 具體來說,裝置的 smallestWidth 是螢幕可用高度和寬度的最小尺寸(您也可以将其視為螢幕的“最小可能寬度”)。無論螢幕的目前方向如何,您均可使用此限定符確定應用 UI 的可用寬度至少為 

<N>

dp。

例如,如果布局要求螢幕區域的最小尺寸始終至少為 600dp,則可使用此限定符建立布局資源 

res/layout-sw600dp/

。僅當可用螢幕的最小尺寸至少為 600dp 時,系統才會使用這些資源,而不考慮 600dp 所代表的邊是使用者所認為的高度還是寬度。smallestWidth 是裝置的固定螢幕尺寸特性;裝置的 smallestWidth 不會随螢幕方向的變化而改變。

裝置的 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

 屬性和 

smallestScreenWidthDp

 配置字段,前者聲明與應用相容的最小 smallestWidth;後者存放裝置的 smallestWidth 值。

如需了解有關設計不同螢幕和使用此限定符的詳細資訊,請參閱支援多種螢幕開發者指南。

可用寬度

w<N>dp

示例:

w720dp

w1024dp

等等
指定資源應該使用的最小可用螢幕寬度,以 

dp

 為機關,由 

<N>

 值定義。在橫向和縱向之間切換時,為了比對目前實際寬度,此配置值也會随之發生變化。

應用為多個資源目錄提供不同的此配置值時,系統會使用最接近(但未超出)裝置目前螢幕寬度的值。 此處的值考慮到了螢幕裝飾元素,是以如果裝置顯示屏的左邊緣或右邊緣上有一些永久性 UI 元素,考慮到這些 UI 元素,它會使用小于實際螢幕尺寸的寬度值,這樣會減少應用的可用空間。

此項為 API 級别 13 中新增配置。

另請參閱 

screenWidthDp

 配置字段,該字段存放目前螢幕寬度。

如需了解有關設計不同螢幕和使用此限定符的詳細資訊,請參閱支援多種螢幕開發者指南。

可用高度

h<N>dp

示例:

h720dp

h1024dp

等等
指定資源應該使用的最小可用螢幕高度,以“dp”為機關,由 

<N>

 值定義。 在橫向和縱向之間切換時,為了比對目前實際高度,此配置值也會随之發生變化。

應用為多個資源目錄提供不同的此配置值時,系統會使用最接近(但未超出)裝置目前螢幕高度的值。 此處的值考慮到了螢幕裝飾元素,是以如果裝置顯示屏的上邊緣或下邊緣有一些永久性 UI 元素,考慮到這些 UI 元素,同時為減少應用的可用空間,它會使用小于實際螢幕尺寸的高度值。 非固定的螢幕裝飾元素(例如,全屏時可隐藏的手機狀态欄)并不在考慮範圍内,标題欄或操作欄等視窗裝飾也不在考慮範圍内,是以應用必須準備好處理稍小于其所指定值的空間。

此項為 API 級别 13 中新增配置。

另請參閱 

screenHeightDp

 配置字段,該字段存放目前螢幕寬度。

如需了解有關設計不同螢幕和使用此限定符的詳細資訊,請參閱支援多種螢幕開發者指南。

螢幕尺寸

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()

 配置方法,其訓示螢幕是否為寬屏。
螢幕方向

port

land

  • port

    :裝置處于縱向(垂直)
  • land

    :裝置處于橫向(水準)

如果使用者旋轉螢幕,它有可能在應用生命周期中發生改變。 如需了解這會在運作期間給應用帶來哪些影響,請參閱處理運作時變更。

另請參閱 

orientation

 配置字段,該字段訓示目前的裝置方向。
UI 模式

car

desk

television

appliance

watch

  • car

    :裝置正在車載手機座上顯示
  • desk

    :裝置正在桌面手機座上顯示
  • television

    :裝置正在電視上顯示,為使用者提供“十英尺”體驗,其 UI 位于遠離使用者的大螢幕上,主要面向方向鍵或其他非指針式互動
  • appliance

    :裝置用作不帶顯示屏的裝置
  • watch

    :裝置配有顯示屏,戴在手腕上

此項為 API 級别 8 中新增配置,API 13 中新增電視配置,API 20 中新增手表配置。

如需了解應用在裝置插入手機座或從中移除時的響應方式,請閱讀确定并監控插接狀态和類型。

如果使用者将裝置放入手機座中,它有可能在應用生命周期中發生改變。 可以使用 

UiModeManager

啟用或禁用其中某些模式。如需了解這會在運作期間給應用帶來哪些影響,請參閱處理運作時變更。
夜間模式

night

notnight

  • night

    :夜間
  • notnight

    :白天

此項為 API 級别 8 中新增配置。

如果夜間模式停留在自動模式(預設),它有可能在應用生命周期中發生改變。在這種情況下,該模式會根據當天的時間進行調整。 可以使用 

UiModeManager

 啟用或禁用此模式。如需了解這會在運作期間給應用帶來哪些影響,請參閱處理運作時變更。
螢幕像素密度 (dpi)

ldpi

mdpi

hdpi

xhdpi

xxhdpi

xxxhdpi

nodpi

tvdpi

anydpi

  • ldpi

    :低密度螢幕;約為 120dpi。
  • mdpi

    :中等密度(傳統 HVGA)螢幕;約為 160dpi。
  • hdpi

    :高密度螢幕;約為 240dpi。
  • xhdpi

    :超高密度螢幕;約為 320dpi。此項為 API 級别 8 中新增配置
  • xxhdpi

    :超超高密度螢幕;約為 480dpi。此項為 API 級别 16 中新增配置
  • xxxhdpi

    :超超超高密度螢幕使用(僅限啟動器圖示,請參閱“支援多種螢幕”中的注釋);約為 640dpi。 此項為 API 級别 18 中新增配置
  • nodpi

    :它可用于您不希望縮放以比對裝置密度的位圖資源。
  • tvdpi

    :密度介于 mdpi 和 hdpi 之間的螢幕;約為 213dpi。它并不是“主要”密度組, 主要用于電視,而大多數應用都不需要它。對于大多數應用而言,提供 mdpi 和 hdpi 資源便已足夠,系統将根據需要對其進行縮放。此項為 API 級别 13 中新增配置
  • anydpi

    :此限定符适合所有螢幕密度,其優先級高于其他限定符。 這對于矢量可繪制對象很有用。 此項為 API 級别 21 中新增配置

六個主要密度之間的縮放比為 3:4:6:8:12:16(忽略 tvdpi 密度)。是以,9x9 (ldpi) 位圖相當于 12x12 (mdpi)、18x18 (hdpi)、24x24 (xhdpi) 位圖,依此類推。

如果您認為圖像資源在電視或其他某些裝置上呈現的效果不夠好,而想嘗試使用 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

 資源,而不考慮鍵盤是否可見。

如果使用者打開硬鍵盤,它有可能在應用生命周期中發生改變。 如需了解這會在運作期間給應用帶來哪些影響,請參閱處理運作時變更。

另請參閱配置字段 

hardKeyboardHidden

 和 

keyboardHidden

,這兩個字段分别訓示硬鍵盤的可見性和任何一種鍵盤(包括軟鍵盤)的可見性。
主要文本輸入法

nokeys

qwerty

12key

  • nokeys

    :裝置沒有用于文本輸入的硬按鍵。
  • qwerty

    :裝置具有标準硬鍵盤(無論是否對使用者可見)。
  • 12key

    :裝置具有 12 鍵硬鍵盤(無論是否對使用者可見)。
另請參閱 

keyboard

 配置字段,該字段訓示可用的主要文本輸入法。
導航鍵可用性

navexposed

navhidden

  • navexposed

    :導航鍵可供使用者使用。
  • navhidden

    :導航鍵不可用(例如,位于密封蓋子後面)。

如果使用者顯示導航鍵,它有可能在應用生命周期中發生改變。 如需了解這會在運作期間給應用帶來哪些影響,請參閱處理運作時變更。

另請參閱 

navigationHidden

 配置字段,該字段訓示導航鍵是否處于隐藏狀态。
主要非觸摸導航方法

nonav

dpad

trackball

wheel

  • nonav

    :除了使用觸摸屏以外,裝置沒有其他導航設施。
  • dpad

    :裝置具有用于導航的方向鍵。
  • trackball

    :裝置具有用于導航的軌迹球。
  • wheel

    :裝置具有用于導航的方向盤(不常見)。
另請參閱 

navigation

 配置字段,該字段訓示可用的導航方法類型。
平台版本(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-rES-rFR/

     的目錄,而是需要兩個包含相應檔案的資源目錄,如 

    drawable-rES/

     和 

    drawable-rFR/

    。然而,實際上您無需将相同的檔案都複制到這兩個位置。相反,您可以建立指向資源的别名。 請參閱下面的建立别名資源。

将備用資源儲存到以這些限定符命名的目錄中之後,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 檔案的一個版本和兩個指向該版本的小型 XML 檔案。(XML 檔案示例如下。)

可繪制對象

要建立指向現有可繪制對象的别名,請使用 

<bitmap>

 元素。例如:

<? xml version = "1.0" encoding = "utf-8" ?>

<bitmap xmlns:android = "http://schemas.android.com/apk/res/android"

    android:src = "@drawable/icon_ca" />

如果将此檔案另存為 

icon.xml

(例如,在備用資源目錄中,另存為 

res/drawable-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>

利用資源提供最佳裝置相容性

要使應用支援多種裝置配置,則務必為應用使用的每種資源類型提供預設資源,這一點非常重要。

例如,如果應用支援多種語言,請始終包含不帶語言和區域限定符的 

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 也可以從備用螢幕密度中找到最佳比對項并根據需要縮放位圖。 但是,為了在所有類型的裝置上提供最佳體驗,您應該為所有三種類型的密度提供備用可繪制對象。

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

 中選擇可繪制對象。

系統使用以下邏輯決定要使用的資源:

android 應用基礎知識(2)---應用資源Android資源

圖 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 步。

淘汰不含此限定符的資源目錄。在該示例中,系統會淘汰所有不含語言限定符的目錄。

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

例外:如果涉及的限定符是螢幕像素密度,則 Android 會選擇最接近裝置螢幕密度的選項。通常,Android 傾向于縮小大型原始圖像,而不是放大小型原始圖像。請參閱支援多種螢幕。

傳回并重複第 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

 被淘汰。

繼續閱讀