編輯:關於Android編程
前言
一入 Android 深似海,相信很多 Android 開發者深有體會,Android 系統版本的碎片化,Android 硬件設備的多樣性,第三方 Rom 的不確定因素。現在想開發一個合格的商業化 App 真的不容易,先不說別的,應用的兼容性就是一項技術和耐心的雙重考驗,想完美適配各種情況可以說是不可能的,往往都是在人力和適配率之間尋找平衡,今天要說的 drawable 就是需要適配的一個重要角色。
配置限定符
對於不同的屏幕密度、不同的設備方向,不同的語言和區域,都會涉及到備選 drawable 資源,在運行時,Android 會檢測當前設備配置並根據具體規則(後面會提到)為應用加載合適的資源。下面是可以使用的配置限定符,需要說明的是這些配置限定符不僅對 drawable 有效,對其他資源類型(如:layout 等)也有效:
移動國家代碼 (MCC):mcc310, mcc310-mnc004, mcc208-mnc00
語言和區域:en, fr, en-rUS 等等
布局方向:ldrtl(從右到左)ldltr(從左到右)
smallestWidth:sw<N>dp 如:sw320dp, sw600dp, sw720dp 等等,屏幕可用高度和寬度的最小尺寸,屏幕的“最小可能尺寸”。
可用寬度:w<N>dp 如:w720dp, w1024dp 等等,指定資源應該使用的最小可用屏幕寬度,以 dp 為單位,由 <N> 值定義。在橫向和縱向之間切換時,為了匹配當前實際寬度,此配置值也會隨之發生變化。
可用高度:h<N>dp 如:h720dp, h1024dp 等等,指定資源應該使用的最小可用屏幕高度,以dp為單位,由 <N> 值定義。 在橫向和縱向之間切換時,為了匹配當前實際高度,此配置值也會隨之發生變化。
屏幕尺寸:small, normal, large, xlarge
屏幕縱橫比:long 寬屏,如 WQVGA、WVGA、FWVGA;notlong 非寬屏,如 QVGA、HVGA 和 VGA
屏幕方向:port 設備處於縱向(垂直),land 設備處於橫向(水平)
UI 模式:car, desk, television, appliance, watch
夜間模式:night 夜間,nontight 白天
屏幕像素密度:ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi, nodpi, tvdpi
觸摸屏類型:notouch, finger
鍵盤可用性:keysexposed, keyshidden, keyssoft
主要文本輸入法:nokeys, qwerty, 12key
導航鍵可用性:navexposed 導航鍵可供用戶使用,navhidden 導航鍵不可用
主要非觸摸導航方法:nonav, dpad, trackball, wheel
平台版本(API 級別):v3, v4, v7 等等,如 v1 對應於 API 級別 1,v4 對應於 API 級別 4
如果你認真研究下每個配置限定符,你就會體會到:想完美適配各種情況可以說是不可能的,其實我們平時最常用的也是基本必須要用的就是屏幕像素密度,這裡有必要詳細的說一下該參數:
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 中引入了此限定符。
六個主要密度之間的縮放比為 3:4:6:8:12:16(忽略 tvdpi 密度)。因此,9x9 (ldpi) 位圖相當於 12x12 (mdpi)、18x18 (hdpi)、24x24 (xhdpi) 位圖,依此類推。
限定符命名規則
可以為單組資源指定多個限定符,並使用短劃線分隔。例如,drawable-en-rUS-land 適用於橫排美國英語設備。
這些限定符必須遵循上面列出的順序,所以上面的列表是有順序的。例如:錯誤:drawable-hdpi-port/,正確:drawable-port-hdpi/
不能嵌套備用資源目錄。例如,您不能擁有 res/drawable/drawable-en/。
值不區分大小寫。在處理之前,資源編譯器會將目錄名稱轉換為小寫,以避免不區分大小寫的文件系統出現問題。 名稱中使用的任何大寫字母只是為了便於認讀。
對於每種限定符類型,僅支持一個值。例如,若要對西班牙語和法語使用相同的 drawable 文件,則您肯定不能擁有名為 drawable-rES-rFR/ 的目錄,而是需要兩個包含相應文件的資源目錄。
Android 匹配最佳 drawable 規則
如果你只使用一個配置限定符,那麼很好匹配,找到符合該配置的 drawable 即可,但當你同時使用多個配置限定符,且同時存在多個 drawable 目錄時,匹配最佳 drawable 就沒那麼簡單了,這裡以 Android Developer 官方的例子說明,例如:現在你的應用包含如下目錄:
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
具體的匹配過程如下:
1、淘汰與設備配置沖突的資源文件:其中 drawable-fr-rCA/ 目錄與 en-GB 區域設置沖突,因而被淘汰(但有個例外,屏幕像素密度是唯一一個未因沖突而被淘汰的限定符,盡管設備的屏幕密度為 hdpi,但是 drawable-port-ldpi/ 未被淘汰,因為此時每個屏幕密度均視為匹配)
2、選擇在上面限定符列表中優先級最高的限定符,先從 MCC 開始,然後下移,看是否有資源目錄包括此限定符,若無則看下一個限定符,在該示例中,除非達到語言限定符,否則答案始終為“否”。
3、若有,則淘汰不含此限定符的資源目錄。在該示例中,系統會淘汰所有不含語言限定符的目錄。所以到這一步符合要求的 drawable 還剩:
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
4、選擇下一個優先級的限定符,重復執行步驟 2, 3, 4。直到只剩下一個目錄,該例中應該是 port, 所以淘汰後只剩:
drawable-en-port/
有兩點需要說明一下:
1、屏幕像素密度是唯一一個未因沖突而被淘汰的限定符,如果涉及的限定符是屏幕像素密度,則 Android 會選擇最接近設備屏幕密度的選項。通常 Android 傾向於縮小大型原始圖像,而不是放大小型原始圖像。
2、如果一個符合限定符的 drawable 都沒有怎麼辦?還能怎麼辦,崩潰呗!
drawable 和 mipmap 的區別和聯系
現在通過 Android Studio 創建工程,默認會創建一系列 mipmap 文件夾,而不是以前的 drawable 文件夾。那麼 mipmap 和 drawable 到底是什麼關系?mipmap 取代了 drawable 了嗎?先看一下官方說明:
drawable/
For bitmap files (PNG, JPEG, or GIF), 9-Patch image files, and XML files that describe Drawable shapes or Drawable objects that contain multiple states (normal, pressed, or focused). See the Drawable resource type.
mipmap/
For app launcher icons. The Android system retains the resources in this folder (and density-specific folders such as mipmap-xxxhdpi) regardless of the screen resolution of the device where your app is installed. This behavior allows launcher apps to pick the best resolution icon for your app to display on the home screen. For more information about using the mipmap folders, see Managing Launcher Icons as mipmap Resources.
這裡先說結論:mipmap 文件夾下,僅僅建議放啟動圖標 (app launcher icons),也就是應用安裝後,會顯示在桌面的那個圖標,而其他的圖片資源等,還是按照以前方式,放在 drawable 文件夾下。
那麼為什麼要把 Launcher Icon 放在mipmap 文件夾下? 下面英文是官方解釋:
Different home screen launcher apps on different devices show app launcher icons at various resolutions. When app resource optimization techniques remove resources for unused screen densities, launcher icons can wind up looking fuzzy because the launcher app has to upscale a lower-resolution icon for display. To avoid these display issues, apps should use the mipmap/ resource folders for launcher icons. The Android system preserves these resources regardless of density stripping, and ensures that launcher apps can pick icons with the best resolution for display.
Make sure launcher apps show a high-resolution icon for your app by moving all densities of your launcher icons to density-specific res/mipmap/ folders (for example res/mipmap-mdpi/ and res/mipmap-xxxhdpi/). The mipmap/ folders replace the drawable/ folders for launcher icons. For xxhpdi launcher icons, be sure to add the higher resolution xxxhdpi versions of the icons to enhance the visual experience of the icons on higher resolution devices.
這裡是我的理解:很多不同的 Launcher App 采用的 Launcher Icon 的大小不一致,而在應用安裝時 Android 資源優化會把 drawable 文件夾下不需要的分辨率資源刪除掉,例如在 xhdpi 的設備上將 drawable-xxhdpi 下的資源刪掉,當然裡面的 Launcher Icon 也會被刪掉,這時如果 Launcher App 采用的 Launcher Icon 大小偏大,而高分辨 xxhdpi 下的 Icon 又被刪掉了,就只能把 xhdpi 下的小尺寸 Icon 進行放大顯示了,這樣就會造成 Launcher Icon 顯示模糊。為了避免上面的問題,就引入了 mipmap,Android 會保證 mipmap 下的資源不會因為資源優化而被刪除,確保大尺寸的 Launcher Icon 可以找到更合適分辨率的 Icon。所以 mipmap 是為 Launcher Icon 而生的,而其它的圖片資源還是放在 drawable 文件夾下,這樣有助於Android 資源優化刪除無用的資源,減少應用體積。
總結
以上就是關於Android中drawable必知的一些規則的全部內容,文章內容對於Android開發者來說很實用,希望對各位有所幫助。
一、情形描述在常使用的頁面布局中,為保持用戶一貫的使用風格,會保持頁面的整體風格相似。除開底部導航外,標題欄是使用頻率較高的另一種頁面布局。如圖所示:在程序猿&ldquo
之前跟大家介紹一個Alibaba的框架dexposed框架,此框架能夠動態的從線上完成一些補丁的工作。但是,由於它的性能和兼容性(不支持ART)所以,很多朋
最終效果圖,點擊save會保存到文件中,點擊show會從文件中讀取出內容並顯示。main.xml<?xml version=1.0 encoding=utf
網上很多關於Android事件分發機制的解釋,大多數描述的都不夠清晰,沒有吧來龍去脈搞清楚,本文將帶你從Touch事件產生到Touch事件被消費這一全過程作