android res 資源匹配目錄 、 drawable與 mipmap的區(qū)別
在res目錄下,有各種各樣的資源文件目錄,這些目錄的名字是有規(guī)則的,為了更好的適配多種設備,我們需要了解這些目錄的命名規(guī)則,及各中限定符的意義,熟悉系統(tǒng)匹配這些資源的規(guī)則。
-
給資源配置限定符
配置限定符是有順序的,它的優(yōu)先順序如下(從高到低):(
res
下的全部資源)-
MCC和MNC
移動國家代碼(MCC)和移動網(wǎng)絡代碼(MNC);
drawable-mcc310-mnc004
是指美國的 Verizon 公司; -
語言和區(qū)域
例如:
en
,fr
,fr-rFR
,fr-rCA
;drawbale-en
,drawable-fr
-
布局方向
ldrtl
:表示“布局方向從右到左”ldltr
:表示“布局方向從左到右”,這是默認的隱式值。layout
,layout-ar
(阿拉伯國家專配layout),layout-ldrtl
-
smallestWidth (新配置限定符, android 3.2引入)
sw<N>dp ,屏幕的基本尺寸
-
sw320dp
適用于
320*320 ldpi
、320*480 mdpi
、480*480 hdpi
-
sw600dp
適用于
600*1024mdpi
(7英寸的平板電腦) -
sw720dp
適用于
720*1280 mdpi
(10英寸平板電腦)
layout-sw320dp
,layout-sw720dp
... -
-
可用寬度(新配置限定符, android 3.2引入):
w<N>dp, w720dp, w1024dp
layout-w720dp
可用高度(新配置限定符, android 3.2引入):h<N>dp
-
屏幕尺寸:
small
,normal
,large
,xlarge
(后被拋棄)layout
,layout-large
... 屏幕縱橫比:
long寬屏
、notlong 非寬屏
圓形屏幕:
round
,notround
屏幕方向:
port
垂直,land
橫向UI模式:car, desk, television, appliance, watch
夜間模式: night, notnight
-
屏幕像素密度DPI: 現(xiàn)在常用的分類限定符
mdpi
、hdpi
、xhdpi
、xxhdpi
、xxxhdpi
drawable
,drawable-xhdpi
,drawable-mdpi
-
觸摸屏類型
notouch
,finger
-
鍵盤可用性
keysexposed
: 設備具有可用的鍵盤;keysoft
: 設備啟用軟鍵盤; -
主要文本輸入法
nokeys
:設備沒有用于文本輸入的硬按鍵;qwerty
:設備具有標準硬鍵盤(無論是否對用戶可見);12key
:設備具有 12 鍵硬鍵盤(無論是否對用戶可見); -
導航鍵可用性
navexposed
:導航鍵可供用戶使用;navhidden
:導航鍵不可用(例如,位于密封蓋子后面); -
主要非觸摸導航方法
nonav:除了使用觸摸屏以外,設備沒有其他導航設施。
dpad:設備具有用于導航的方向鍵。
trackball:設備具有用于導航的軌跡球。
wheel:設備具有用于導航的方向盤(不常見)
-
平臺版本(API 級別)
設備支持的 API 級別。例如,v1 對應于 API 級別 1(帶有 Android 1.0 或更高版本系統(tǒng)的設備),v4 對應于 API 級別 4(帶有 Android 1.6 或更高版本系統(tǒng)的設備).
-
-
屏幕密度
現(xiàn)在常用的屬性是屏幕密度:
-
六種通用的密度:
ldpi(低): ~120 dpi 3
mdpi(中):120~160dpi 正常尺寸 4
hdpi(高):160~240dpi 6
xhdpi(超高):240~320dpi 8
xxhdpi(超超高):320~480dpi 12
-
xxxhdpi(超超超高):480~640dpi 16
只針對啟動圖標才需要提供xxxhdpi
注:最后一列為dpi之間的比例,用于轉(zhuǎn)換。(例:如果
xhdpi
里不存在資源,可以從xxhdpi
中去同名id的資源,縮放0.66(8/12)即可)
-
-
匹配資源的實現(xiàn)邏輯:
系統(tǒng)通過以下過程確保任何給定資源(id)在當前屏幕上都能保持盡可能最佳的顯示效果:
其實是對某一個具體的資源id進行匹配。
-
使用適當?shù)馁Y源
根據(jù)當前屏幕的尺寸和密度,使用應用中提供的任何尺寸和密度特定資源,尋找最佳匹配項。
-
如果沒有匹配資源目錄
系統(tǒng)將使用默認資源,并按需要向上 或向下擴展,以匹配當前的屏幕尺寸和密度。
注意: “默認”資源是指未標記配置限定符的資源。例如,
drawable/
中的資源是默認可繪制資源。 系統(tǒng)假設默認資源設計用于基線屏幕尺寸和密度,即 正常屏幕尺寸和中密度。 因此,系統(tǒng)對于高密度屏幕向上擴展默認密度 資源,對于低密度屏幕向下擴展。 -
存在資源目錄在,但在目錄中沒有指定的資源,不一定會使用默認資源
系統(tǒng)在縮放時可能 改用其他密度特定資源提供更好的 效果。例如,查找低密度資源但該資源不可用時, 系統(tǒng)會縮小資源的高密度版本,因為 系統(tǒng)可輕松以 0.5 為系數(shù)將高密度資源縮小至低密度資源,與以 0.75 為系數(shù) 縮小中密度資源相比,偽影更少。
如果當前手機分辨率為drawable-xxhdpi,且沒有發(fā)現(xiàn)對應的資源時,會優(yōu)先去xxxhdpi去尋找, 接著向更高密度去尋找,沒有后,在向下尋找,依次為:
drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi。
-
務必要為應用使用的每種資源類型提供默認資源,這關系到應用是否會發(fā)生crash。
android 如何查找最佳匹配資源
系統(tǒng)邏輯:
假設以下可繪制對象目錄分別包含相同圖像id的不同版本:
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
而設備的配置如下:
語言區(qū)域 = en-GB
屏幕方向 = port
屏幕像素密度 = hdpi
觸摸屏類型 = notouch
主要文本輸入法 = 12key
邏輯規(guī)則如下:
-
淘汰所有與設備配置沖突的資源文件。
會去遍歷所有的設備限定符,把所有沖突的限定符淘汰掉, 即全部的設備配置的限定符都會在這里被便遍歷,淘汰掉與之沖突的資源文件
drawable-fr-rCA/ 目錄與 en-GB 語言區(qū)域沖突,因而被淘汰。
注: 其他的設備限定符未與當前目錄沖突,故而不淘汰。
剩余:
drawable/
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
例外:屏幕像素密度是唯一一個未因沖突而被淘汰的限定符。 盡管設備的屏幕密度為 hdpi,但是 drawable-port-ldpi/ 未被淘汰,因為此時每個屏幕密度均視為匹配。
這也表明要為除了dpi限定符之外的
資源id
提供默認的資源放入默認目錄里,例如drawable,string下的資源id
, 不然會因找不到資源而發(fā)生crash
. -
選擇列表(表 2)中(下一個)優(yōu)先級最高的限定符。(先從 MCC 開始,然后下移。)
2,3,4步里是對同一個限定符做處理。處理完4后,經(jīng)過5,若仍有多個資源目錄,會再次返回2,處理下一個限定符。
-
是否有資源目錄包括此限定符?
- 若無,請返回到第 2 步,看看下一個限定符。(在該示例中,除非達到語言限定符,否則答案始終為“否”。)
- 若有,請繼續(xù)執(zhí)行第 4 步。
-
淘汰不含此限定符的資源目錄。在該示例中,系統(tǒng)會淘汰所有不含語言限定符的目錄。
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
。
匹配資源的優(yōu)化
盡管對所請求的每個資源均執(zhí)行此程序,但是系統(tǒng)仍會對某些方面做進一步優(yōu)化。 例如,系統(tǒng)一旦知道設備配置,即會淘汰可能永遠無法匹配的備用·資源。 比如說,如果配置語言是英語(“en”),則系統(tǒng)絕不會將語言限定符設置為非英語的任何資源目錄包含在選中的資源池中(不過,仍會將不帶語言限定符的資源目錄包含在該池中)。
根據(jù)屏幕尺寸(small, large等(已被淘汰))限定符選擇資源時,如果沒有更好的匹配資源,則系統(tǒng)將使用專為小于當前屏幕的屏幕而設計的資源(例如,如有必要,大尺寸屏幕將使用標準尺寸的屏幕資源)。 但是,如果唯一可用的資源大于當前屏幕,則系統(tǒng)不會使用這些資源,并且如果沒有其他資源與設備配置匹配,應用將會崩潰(例如,如果所有布局資源均用 xlarge 限定符標記,但設備是標準尺寸的屏幕)。
所以不建議使用屏幕尺寸,更多使用dpi。
注:限定符的優(yōu)先順序 比與設備完全匹配的限定符數(shù)量更加重要。例如,在上面的第 4 步中,列表剩下的最后選項包括三個與設備完全匹配的限定符(方向、觸摸屏類型和輸入法),而 drawable-en 只有一個匹配參數(shù)(語言)。但是,語言的優(yōu)先順序高于其他兩個限定符,因此 drawable-port-notouch-12key 被淘汰。
限定符命名規(guī)則:
-
可以為單組資源指定多個限定符,使用短劃線分隔
例如:
drawable-en-rUS-land
表示適用于橫排美國英語設備 -
限定符必須遵循上面列出的優(yōu)先級順序...
若限定符不符合優(yōu)先級順序,編譯查找資源的時候會報錯(
invalid resource directory name
) -
不能嵌套備用資源目錄
不能有
res/drawable/drawable-en/
-
名字不區(qū)分大小寫
編譯時編譯器會把目錄名稱轉(zhuǎn)化為小寫, 以避免不區(qū)分大小寫的文件系統(tǒng)出現(xiàn)問題。
-
對于每種限定符類型,僅支持一個值
例如對同一個語言不可能會出現(xiàn)
drawable-rES-rFR
, 而是兩個目錄drawable-rES
,drawable-rFR
.
對常用限定符舉例說明:
drawable-xxhdpi
, mipmap-xxhdpi
, values-fr
, values-zh-rCN
drawable 與mipmap的區(qū)別
引入mipmap的原因:在apk應用于手機時,系統(tǒng)會去選擇對應的資源目錄,有時啟動圖標ic_launcher
會不合適,但是其他的資源目錄已經(jīng)被過濾掉了,這樣導致了在手機顯示上,啟動圖標不正確的現(xiàn)象。而mipmap
可以保留著一個ic_launcher
,而且也僅僅需要一個分辨率的icon,自動會縮放成其他分辨率的ic_launcher
將所有啟動器圖標放在 res/mipmap-[density]/
文件夾中,而非 res/drawable-[density]/
文件夾中。無論安裝應用的設備屏幕分辨率如何,Android 系統(tǒng)都會將資源保留在這些密度特定的文件夾中,例如 mipmap-xxxhdpi
。此 行為可讓啟動器應用為您的應用選擇要顯示在主 屏幕上的最佳分辨率圖標。
同時,
mipmap
建議只存放應用啟動圖標,其他的仍放在drawable下。
定位的區(qū)別
-
drawbale
For bitmap files (PNG, JPEG, or GIF), 9-Patch image files, and XML files .
資源類型:位圖文件(
.png
,.9.png
,jpg
,.gif
)或編譯為以下可繪制對象資源子類型的XML文件- 位圖文件
- 九宮格(可調(diào)整大小的位圖),點9圖
- 狀態(tài)列表
- 形狀
- 動畫可繪制對象
- 其他科繪制對象
-
mipmap
For app launcher icons.
適用于不同啟動器圖標密度的可繪制對象文件。
icon放置在mipmap文件夾還可以讓程序的launcher圖標自動擁有跨設備密度展示的能力,例如,一臺屏幕密度是xxhdpi的設備可以自動加載mipmap-xxxhdpi下的icon來作為應用程序的launcher圖標,這樣圖標看上去就會更加細膩。
總結---重要!!!
要使應用支持多種設備配置,務必要為使用的每種資源類型提供默認資源,這一點十分十分的重要。
把多個分辨率的
ic_launcher
-啟動圖標放入mipmap
下,把其他的圖片資源放進drawable-xxhdpi
。
- 給資源目錄命名時要多注意,是否符合規(guī)則, 是否會因為缺少默認資源而導致程序在某些情況下發(fā)生
crash
。
參考鏈接
android developer 支持多種屏幕
android developer 提供資源
android developer android 匹配資源規(guī)則
android developer 可繪制對象資源
android developer blog 關于mipmap的建議