天天看點

Android drawable圖檔适配Android drawable圖檔适配

Android drawable圖檔适配

Android機型衆多,螢幕尺寸、分辨率也有很多種,如何适配各種機型也是Android的技能之一。

适配的目的:

  1. 提高圖檔顯示的品質
  2. 減少圖檔的記憶體占用
  3. 減少cpu性能的使用

一·先說mipmap

  1. Android studio在建立App項目裡,自動在res裡會建立幾個mipmap檔案夾,裡面是幾張icon圖示
  2. 根據Android官方的描述,mipmap僅僅用于存放APP啟動圖示,可由Image Asset Studio生成。Image Asset Studio會生成mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi五種尺寸的圖示。
  3. 自己使用的圖檔放在對應的drawable檔案夾裡
  4. 圖示最好不要随意定義尺寸,分辨率過低會模糊,過高徒增APK包大小。各種密度下的圖示建議尺寸為
密度 建議尺寸
mdpi 48*48
hdpi 72*72
xhdpi 96*96
xxhdpi 144*144
xxxhdpi 192*192
Android drawable圖檔适配Android drawable圖檔适配

二·drawable圖檔适配

相關概念

dpi

每英寸點數,全稱dots per inch。用來表示螢幕密度,即螢幕實體區域中的像素量。高密度螢幕比低密度螢幕在給定實體區域的像素要多。

ppi:實體每英寸的像素,由硬體确定;dpi是由系統根據ppi來确定的。

dp

即dip,全稱device independent pixel。裝置獨立像素,是一種虛拟像素機關,用于以密度無關方式表示布局次元或位置,以確定在不同密度的螢幕上正常顯示UI。在160dpi的裝置上,1dp=1px。

density

裝置的邏輯密度,是dip的縮放因子。以160dpi的螢幕為基線,density=dpi/160。

getResources().getDisplayMetrics().density

sp

縮放獨立像素,全稱scale independent pixel。類似于dp,一般用于設定字型大小,可以根據使用者設定的字型大小偏好來縮放。

文字不适應dp的原因,Android可以在設定頁面設定字型的大小(型号為:小、中、大,可能還有其他型号大小,中型 1sp = 1dp),修改的就是sp

Android drawable圖檔适配Android drawable圖檔适配
Android drawable圖檔适配Android drawable圖檔适配
6種通用密度

Android系統為了簡化開發者為多種螢幕設計使用者界面的方式,Android将實際螢幕尺寸和範圍作了通用規定,稱作“根據可用螢幕寬度管理螢幕尺寸的新技術”。

通用密度是以mdpi(中)為基線配置的,此基線基于第一代Android裝置(T-Mobile G1)的螢幕配置。

六種通用密度為

密度 dpi範圍 dp與px關系(手機通用比對,不包含全部)
ldpi(低) ~120dpi (0.75)1dp = 0.75px
mdpi(中) ~160dpi (1.0)1dp = 1px
hdpi(高) ~240dpi (1.5)1dp = 1.5px
xhdpi(超高) ~320dpi (2.0)1dp = 2px
xxhdpi(超超高) ~480dpi (3.0)1dp = 3px
xxxhdpi(超超超高) ~640dpi (4.0)1dp = 4px
Android系統圖檔适配原則

  Android為了更好地優化應用在不同螢幕密度下的使用者體驗,在項目的res目錄下可以建立drawab-[density](density為6種通用密度名)目錄,開發者在進行APP開發時,針對不同的螢幕密度,将圖檔放置于對應的drawable-[density]目錄,Android系統會依據特定的原則來查找各drawable目錄下的圖檔。查找流程為:

  1. 先查找和螢幕密度最比對的檔案夾。

    例如,目前裝置螢幕密度dpi為160,則會優先查找drawable-mdpi目錄;如果裝置螢幕密度dpi為420,則會優先查找drawable-xxhdpi目錄。

  2. 如果在最比對的目錄沒有找到對應圖檔,就會向更高密度的目錄查找,直到沒有更高密度的目錄。

    例如,在最比對的目錄drawable-mdpi中沒有查找到,就會查找drawable-hdpi目錄,如果還沒有查找到,就會查找drawable-xhdpi目錄,直到沒有更高密度的drawable-[density]目錄。

  3. 如果一直往高密度目錄均沒有查找,Android就會查找drawable-nodpi目錄。

    drawable-nodpi目錄中的資源适用于所有密度的裝置,不管目前螢幕的密度如何,系統都不會縮放此目錄中的資源。

    是以,對于永遠不希望系統縮放的資源,最簡單的方法就是放在此目錄中;同時,放在該目錄中的資源最好不要再放到其他drawable目錄下了,避免得到非預期的效果。

    如果在drawable-nodpi目錄也沒有查找到,系統就會向比最比對目錄密度低的目錄依次查找,直到沒有更低密度的目錄。

    例如,最比對目錄是xxhdpi,更高密度的目錄和nodpi目錄查找不到後,就會依次查找drawable-xhdp、drawable-hdpi、drawable-mdpi、drawable-ldpi。

圖檔适配查找流程 與 流程圖

流程

  舉個例子,假如目前裝置的dpi是320,系統會優先去drawable-xhdpi目錄查找,如果找不到,會依次查找xxhdpi → xxxhdpi → hdpi → mdpi → ldpi。對于不存在的drawable-[density]目錄直接跳過,中間任一目錄查找到資源,則停止本次查找。

總結一下圖檔查找過程:優先比對最适合的圖檔→查找密度高的目錄(升序)→查找密度低的目錄(降序)。

流程圖

Android drawable圖檔适配Android drawable圖檔适配
圖檔的縮小與放大

  前述說到Android為了能夠更好地适配各種螢幕,會依據目前裝置的dpi對drawable-[density]目錄中的圖檔進行縮放,那麼什麼情況下圖檔被放大,什麼情況下圖檔被縮小呢?

  圖檔的縮放會消耗一些cpu性能

  • 如果圖檔所在目錄為比對目錄,則圖檔會根據裝置dpi做适當的縮放調整。
  • 如果圖檔所在目錄dpi低于比對目錄,那麼該圖檔被認為是為低密度裝置需要的,現在要顯示在高密度裝置上,圖檔會被放大。
  • 如果圖檔所在目錄dpi高于比對目錄,那麼該圖檔被認為是為高密度裝置需要的,現在要顯示在低密度裝置上,圖檔會被縮小。
  • 如果圖檔所在目錄為drawable-nodpi,則無論裝置dpi為多少,保留原圖檔大小,不進行縮放。

縮放計算

那麼六種通用密度下的縮放倍數是多少呢?以mdpi為基線,各密度目錄下的放大倍數(即縮放因子density)如下

密度 放大倍數
ldpi(低) 0.75
mdpi(中) 1.0
hdpi(高) 1.5
xhdpi(超高) 2.0
xxhdpi(超超高) 3.0
xxxhdpi(超超超高) 4.0

縮放倍數(縮放因子)計算方法:對于任意裝置,各drawable-[density]目錄下的圖檔放大倍數的計算公式

Android drawable圖檔适配Android drawable圖檔适配
圖檔縮放後的記憶體計算
  1. 圖檔占用的記憶體與圖檔顯示的控件沒有關系。
  2. 圖檔縮小不會增加記憶體,會增加cpu的消耗。
  3. 圖檔放大增加記憶體,增加cpu的消耗。
  4. 如果圖檔顯示控件的寬高 比 加載到記憶體的圖檔寬高(縮放後的圖檔)更大,則圖檔會失真

圖檔記憶體與寬高的關系:

- 圖檔記憶體占用 = bitmap width * bitmap height * 顔色深度(機關Byte)

- 圖檔的寬高與圖檔的原始寬高、圖檔在哪個檔案夾、裝置dpi有關

- bitmap width = 原始寬高 * 裝置dpi / 圖檔所在檔案夾dpi

切圖與放的位置

  關于切圖的選取,Android官方給的建議,各種密度都給出一套圖,分别放置在對應的drawable目錄下,這種适配是最好的。但也存在問題,一是這種方式會增大安裝包的大小;二是很多公司UI在出圖時隻會出一套。

  在這種情況下,怎麼使用好這一套切圖呢?由于目前的Android智能手機的螢幕基本都在1080p了,螢幕的dpi多數都處于320~480,為了更好地适配,同時為了節省記憶體成本,建議将切圖放置在drawable-xxhdpi目錄,同時建議UI針對該密度的裝置設計切圖。

Android TV切圖

電視的dpi一般都較低

Android drawable圖檔适配Android drawable圖檔适配

機頂盒切圖放置位置和手機不同

  1. 在TV盒子上,UI 按照給手機出切圖的方式導出的 xxhpi、xhdpi、hdpi、mdpi等切圖,不能直接放置在對應 dpi 的 drawable 目錄下。
  2. 比如,UI 以 1080 * 1920 為基準,導出的一比一的切圖,在手機上,對應的是 xxhdpi,因放置到手機的 drawable-xxhdpi 檔案夾中。而在機頂盒上(假設機頂盒分辨率為 1280 * 720 160dpi 或 1920 * 1080 240dpi),對應的應該是 hdpi,因放置到 drawable-hdpi 檔案夾中,機頂盒需要其他切圖,應該以 hdpi 為基準進行放大或縮小出圖。

總結:

  為了适配大部分機頂盒,UI 應該按照 1920 * 1080 出圖,1920 * 1080 效果圖導出的1比1的切圖,對應的是 hdpi (而非手機開發時候的 xxhdpi)。給 drawable-xhdpi、drawable-hdpi、drawable-mdpi 的切圖。編碼時,在 value-w1280p、 value-w960p 下分别設不同的值(value-w960p 下的值可按 value-w1280p 中的值等比例縮放獲得)。