你總應該将諸如圖片,字符之類的資源從應用代碼中提取出來,這樣就可以單獨的維護他們。你還應該通過将它們按特定的資源目錄名稱分組的方式,為特定的設備配置提供可替換資源。安卓系統在運行時根據當前配置實用合适的資源。例如,你可能會想根據不同屏幕尺寸提供不同的界面布局,根據語言設置提供不同的字符串。
一旦提取了應用資源, 你就可以使用項目中R類生成的資源ID來使用它們。訪問資源文檔讨論了如何使用應用資源。本文檔展示了如何為安卓項目資源分組和為特定設備配置提供可替換資源。
你應該将每種類型資源放到項目res/目錄的特定子目錄中。例如,下面是一個示例項目的文件結構:
正如你在這個例子中所見,res/目錄包含了所有的資源(在子目錄中):一個圖片資源,兩個布局資源,和一個字符串資源文件。資源目錄的命名是非常重要的,如表1中所述。
表1.項目res/目錄中支持的資源目錄。
警告:不能直接在res/目錄保存資源——這将導緻編譯錯誤。
要了解某種資源類型的詳細信息,請參考資源類型文檔。
保存在表1中定義的子目錄中的資源是你的“默認”資源。這就是說,這些資源定義了應用的默認設計和内容。但是,不同的安卓設備可能調用不同的資源類型。例如,如果一個設備有比普通設備更大的屏幕,那麼你應該提供不同的布局資源來利用額外的屏幕空間。或者,如何一個設備有不同的語言設置,那麼你應該提供不同的字符資源來翻譯用戶界面的文本。要為不同的設備配置提供不同的資源,除了默認資源,你還需要提供可替換資源。
圖1。兩個不同的設備,每個都使用不同的布局資源。
幾乎每種應用都應該提供可替換資源以支持特定的設備配置。例如,你應該為不同的屏幕尺寸提供可替換的可繪制資源,為不同的語言提供可替換的字符資源。安卓系統在運行時檢測當前設備的配置并為應用讀取适合的資源。
為一組資源指定特定配置的可替換資源:
1. 在res/創建一個新的目錄,按照<resources_name>-<config_qualifier>的格式命名。
<resources_name> 是相應默認資源的目錄名稱(表1中定義的)。
<qualifier> 表示一個單獨配置的名稱,它是這些資源将要使用的配置。(表 2中定義)
你可以附加多個<qualifier>(譯者注:上面提到的修飾符)。每個單獨的修飾符帶有一個破折号。
警告:附加多個修飾符的時候,你必須按照表2所列相同的順序排列他們。如果修飾符排序錯誤,這些資源将被忽略。
2. 在這個新目錄中保存各自的可替換資源。這些資源文件必須按照默認資源文件完全相同的名稱命名。
例如,下面是一些默認和可替換資源:
那個目錄的hdpi修飾符用于高密度屏幕的設備。這些可繪制物體目錄的每個圖片都用于特定屏幕尺寸的大小調整,但是,文件名稱必須完全相同。這樣,用來引用icon.png和background.png圖片的資源ID就總是一樣的,不過安卓系統通過比較設備配置信息和資源目錄名稱的修飾符來挑選最适合當前設備的每個資源版本。
安卓系統支持多種配置修飾符,你可以通過用破折号分隔每個修飾符來為一個目錄名稱添加多個修飾符。表2列出了有效的配置修飾符,按照優先順序——如果為資源目錄使用多個修飾符,你必須以這張表中列出的順序将他們添加到目錄名稱中。
表2。配置修飾符名稱。
注意:一些修飾符是自動安卓1.0添加的,所以并不是所有版本的安卓系統都支持所有修飾符。使用新的修飾符将隐含地添加了平台版本修飾符,以讓舊的設備确保忽略它。例如,使用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/,他們包含了相應的文件。不過,你不需要真的在兩個位置複制同樣的文件。相反,你可以創建資源的别名(譯者注:可理解為快捷方式)。參考下面的創建别名資源。
當你将這些可替換資源保存到使用這些修飾符定義的目錄中後,安卓系統會根據當前設備配置自動應用資源。每次需要資源的時候,安卓系統檢測包含請求資源文件的可替換資源目錄,然後找到最适合的資源(後面讨論)。如果沒匹配特定設備的可替換資源,那麼安卓系統會使用相應的默認資源(沒有包含配置修飾符的特定資源類型的一組資源)。
當你有想用于多個設備配置(但不想提供默認資源)的資源時,你不必将同樣的資源放到多個可替換資源目錄。相反,你可以(在某些情況下)創建作為保存在默認資源目錄資源别名的可替換資源。
注意:不是所有資源都支持可以向其他資源創建别名的機制。特别是,動畫,菜單,原始數據,和其他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>元素。例如:
如果将這個文件保存為icon.xml(在一個可替換資源目錄,如res/drawable-en-rCA/),它被編譯成一個你可以用R.drawable.icon引用的資源,但實際上是R.drawable.icon_ca資源的别名(保存在res/drawable/目錄)。
要創建已存在布局的别名,使用<include>元素,包裝在<merge>标簽中。例如:
如果你将這個文件保存為main.xml,它會被編譯成可以使用R.layout.main引用的資源,但實際上是R.layout.main_ltr資源的别名。
要創建一個已存在字符串的别名,簡單的使用想要用作新字符串的值便可。例如:
R.string.hi資源現在成為了R.string.hello的别名。
Other simple valueswork the same way. For example, a color:
為了讓你的應用支持多個設備配置,總是為應用使用的每種資源類型提供默認資源是非常重要的。
例如,如果應用支持多種語言,總要包含一個沒有語言和區域修飾符的values/目錄(在這裡保存了字符串)。相反如果你将所有的字符串都放到帶有語言和區域修飾符的目錄中,那麼應用在設置了應用所不支持的語言的設備上将會崩潰。但是隻要提供了默認的values/資源,那麼應用會正确的運行(盡管用戶不理解那種語言——這也比崩潰要好)。
同樣的,如果你根據屏幕朝向提供了不同的布局資源,應該采用一個朝向為默認布局。例如,保留一個作為默認布局,如使用layout/用于水平布局,layout-port/用于豎直布局,而不是為layout-land/提供水平布局資源和為layout-port/提供豎直布局資源。
提供默認資源之所以重要不僅因為應用可能會運行在非預期的配置上,也應為新版本的安卓系統有時會添加舊版本不支持的配置修飾符,那麼當就舊版本的安卓系統運行你的應用時,如果你沒提供默認資源它會崩潰,因為它不能使用帶有新修飾符命名的資源。例如,如果你的minSdkVersion設置為4,并将所有可繪制資源限定為使用夜間模式(night 或notnight,API級别8添加),那麼API級别的設備将不能使用你的可繪制資源并會崩潰。這種情況,你也許想要notnight做為默認資源,因此你應該去掉那個修飾符,因此你的資源既可以處于drawable/也可以處于drawable-night/。
因此,為了提供最佳的設備兼容性,總要為保持應用可以正常運行提供默認資源。然後使用配置修飾符創建特定設備配置的可替換資源。
這個規則有一個例外:如果應用的minSdkVersion設置為4或更高,當提供了屏幕密度修飾符的可替換資源時,你确實不需要默認的可繪制資源。即便沒有默認可繪制資源,安卓系統也可以在可替換的屏幕密度之間找到最合适的資源并在必要時縮放位圖。但是,為了在所有設備上獲得最佳體驗,你應該為所有3種密度類型提供可替換的可繪制資源。
當你請求一個提供的可以換資源時,安卓系統在運行根據當前設備配置選擇可以換資源來使用。為了展示安卓系統如何選擇一個可替換資源,假設下面的每個可繪制物體目錄都包含同樣圖片的不同版本:
然後假定下面是設備的配置:
通過比較設備配置與可用的可替換資源,安卓系統從drawable-en-port選擇了可繪制物體。
系統确定使用那個資源的決定使用了如下邏輯:
圖2。安卓系統如何找到最合适的資源的流程圖。
1. 剔除與設備配置相抵觸的資源。
drawable-fr-rCA/ 目錄被剔除,因為它區域修飾符與所需區域相抵觸了。
警告:屏幕像素密度是一種不會由于配置原因被剔除的修飾符。即便設備的屏幕密度是hdpi,drawable-port-ldpi/也不會被剔除,因為此刻每個屏幕密度都被看作一個匹配。更多有用的信息可以參考支持多屏文檔。
2. 選擇列表中(表2)最高優先(接下來)的修飾符。(從MCC開始,然後向下移動)
3. 有任何資源目錄包含這個修飾符嗎?
如果為否,回到第2步并查找下一個修飾符。(這個例子中,回答是“否”直到找到語言修飾符。)
如果為是,繼續第4步。
4. 剔除不包含這個修飾符的資源目錄。這個例子中,系統剔除了所有不包含語言修飾符的目錄:
例外:如果問題是屏幕像素密度,系統會選擇最接近設備屏幕密度的選項。通常,相較于放大一個較小的原始圖片安卓系統更偏好選擇一個較大的原始圖片來縮小。參考支持多屏文檔了解更多信息。
5. 返回重複步驟2,3,和4直到僅剩一個目錄為止。這個例子中,屏幕朝向是下一個有任何适合的修飾符的選擇。因此,沒有指定屏幕朝向的資源被剔除:
保留的目錄是 drawable-en-port.
盡管這個處理會為每個請求的資源執行,系統會近一步優化一些方面。一種優化是一旦知道了設備的配置,它會剔除永遠不會匹配的可替換資源。例如,如果配置的語言是英語("en"),那麼任何擁有設為其他不是英語的語言修飾符的資源将永遠不會被包含到資源檢測池中(盡管沒有語言修飾符的資源目錄仍然包含在内。譯者注:指待檢測的匹配資源目錄列表)。
當根據屏幕大小修飾符選擇資源時,如果沒有更加合适的資源,系統會使用設計用于比當前屏幕更小屏幕尺寸的資源(例如,必要時大屏會使用普通屏幕的資源)。但是,如果僅有的可用資源的尺寸比當前屏幕大,那麼系統不會使用它們,并且如果沒有其他适合設備配置的資源你的應用會崩潰(例如,如果所有的資源都标有xlarge修飾符,但設備是普通大小的屏幕)。
注意:修飾符(表2中)的優先要比精确匹配設備的數量更重要。例如,在上面的第4步中,列表中的最後選擇包含了3個精确匹配設備的選項(朝向,觸屏類型,和輸入方法),但drawable-en僅有一個匹配(語言)的參數。但是,語言比其他的修飾符有更高的優先,因此 drawable-port-notouch-12key出局了(:>)。
要了解更多關于如何在應用中使用資源的信息,繼續閱讀訪問資源文檔。
百度首發地址:《android中文開發向導》
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!