Android的碎片化已經被噴了好多年,隨着國內手機廠商的崛起,碎片化也愈來愈嚴重,根據OpenSignal的最新調查,2014年市面上有18796種不一樣的Android設備,做爲開發者,一個沒法迴避的難題就是須要適配各類各樣奇奇怪怪的機型。html
設備機型不一樣必然也會致使屏幕大小和分辨率(Resolution)的不一樣,可是不管分辨率有多大,屏幕有多大,咱們手指觸控範圍的大小不會發生變化,因此最優的適配方式應該是指定大小的控件在全部的設備上的顯示都同樣。android
Android的官方文檔對此也有明確的說明web
When adding support for multiple screens, applications do not work directly with resolution; applications should be concerned only with screen size and density, as specified by the generalized size and density groups.數組
因此,適配應該與分辨率無關,只與屏幕大小和屏幕密度相關,如下是與單位相關的術語:app
(1) Screen size 屏幕的尺寸,即對角線長度(單位inch-英寸)ide
(2) Resolution 分辨率,即屏幕的總像素點數(width * height)佈局
(3) Screen Density屏幕密度,即每單位英寸包含的像素點數(dots/inches)
字體
(4)Density-independent pixel (dp或dip) 密度無關像素,或者說是與屏幕密度無關的像素。標準是160dip,即1dp對應1個pixel,計算公式如:px = dp * (dpi / 160),屏幕密度越大,1dp對應的像素點越多。
動畫
通常表示是手機的實際物理尺寸,屏幕尺寸指屏幕的對角線的長度,單位是英寸,1英寸=2.54釐米。好比常見的屏幕尺寸有3.五、3.七、4.二、5.0、5.五、6.0等。ui
屏幕上顯示的像素個數,單位尺寸內像素點越多,顯示的圖像就越清楚。單位是px,1px=1個像素點。
分辨率720*1280表示手機水平方向的像素爲720,垂直方向爲1280.
市場上主流分辨率有:480*800、 720*1280、 1080*1920(其餘的早該淘汰了,忽略不計)。
表示屏幕每英寸(inch)的物理長度內包含的像素點數(dots),即屏幕像素密度。 單位是dpi( Dots Per Inch)
DPI(Dots Per Inch)是印刷行業中用來度量空間點密度用的,這個值是打印機每英寸能夠噴的墨汁點數。計算機顯示設備從打印機中借鑑了DPI的概念,因爲計算機顯示設備中的原子單位不是墨汁點而是像素,因此就創造了PPI(Pixels Per Inch),這個值是屏幕每英寸的像素數量,即像素密度(Screen density)。因爲各類緣由,目前PPI(主要是iOS)和DPI(主要在Android中)都會用在計算機顯示設備的參數描述中,不過兩者的意思是同樣的,都是表明像素密度。
Android設備用DPI來表示屏幕密度(Density),屏幕密度大就表示一個Inch包含的Dot比較多。160DPI的屏幕就表示一個Inch包含160個Dot,320DPI的屏幕表示一個Inch有320個Dot,因此說Dot的大小是不固定的。高DPI屏幕顯示的元素會比較精細(看起來會比較小),低DPI屏幕顯示的元素相對來講就比粗糙(看起來會比較大)。
一般咱們說一個設備是多少寸時,指的是屏幕對角線(Diagonal)長度是多少inch,因此用對角線的像素值(px)除以對角線長度(inch),就能夠計算出PPI。
PPI 計算公式
爲了簡化適配工做,Android根據屏幕大小(Inch)和屏幕密度(DPI)對設備作了以下劃分:
你須要把對應dpi的資源放到對應的目錄就能夠了,Android會根據dpi自動選擇資源,目錄規則以下:
drawable-mdpi/asset.png
drawable-hdpi/asset.png
drawable-xhdpi/asset.png
...
能夠看出Android中mdpi與iOS中的1x multiplier所表明的PPI是同樣的,xhdpi與iOS的2x multiplier所表明的PPI同樣,如圖:
既然有那麼多不一樣分辨率、不一樣大小的屏幕,使用PX必然會致使適配困難,爲了進一步簡化適配工做,Android爲咱們提供了一個虛擬的像素單位 - DP 或者 DIP (Density-Independent pixel),固然也能夠理解爲 Device-Independent Pixel,即與設備屏幕密度無關的像素。爲何說是虛擬呢,由於它的大小不是一個物理(Phisical)值,而是由操做系統根據屏幕大小和密度動態渲染出來的。
PX跟DP之間的換算關係很簡單:
px = dp * (dpi / 160)
舉例來講,小米Pad的屏幕密度爲326dpi,若是須要顯示的圖片大小爲20dp,那麼就須要提供一個 20*(326/160)=40px
的圖片才能達到最佳顯示效果,若是還要適配一個163dpi的屏幕,那麼還須要再提供一個20*(163/160)=20px
的圖片。
那麼一個20dp的圖片,在不一樣設備上的顯示效果如何呢?咱們以iPad爲例來講明。
iPad 屏幕參數
iPad2 和 iPad Retina的物理尺寸都是 9.7 inch,不一樣的是分辨率和PPI,一個是1024x768 / 132ppi,另外一個是2048x1536 / 264ppi,分別計算一下20dp對應多少inch
ipad2 = 20 * (132 / 160) * (7.9 / (math.sqrt(1024 * 1024 + 768 * 768))) ipad_retina = 20 * (264 / 160) * (7.9 / (math.sqrt(2048 * 2048 + 1536 * 1536)))
計算結果都是0.1018359375,這就是dp的功能,它能保證在全部的設備上顯示的大小都同樣。
SP 全稱是 Scale-independent Pixels,用於字體大小,其概念與DP是一致的,也是爲了保持設備無關。由於Android用戶能夠根據喜愛來調整字體大小,因此要使用sp來表示字體大小。
res目錄下存放項目中的全部動畫、圖片、佈局、字符串等資源。一般圖標放在mipmap目錄下,圖片放在drawable目錄下,佈局放在layout目錄下,字符串放在values目錄下, 下面是詳細描述。
定義預先肯定的動畫資源。
Tween動畫保存在res/anim/
目錄下,經過R.anim
類來訪問.
Frame動畫保存在res/drawable/
目錄下,經過 R.drawable
類來訪問.
備註:動畫分爲兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現方式可使視圖組件移動、放大、縮小以及產生透明度的變化;Frame動畫,傳統的動畫方法,經過順序的播放排列好的圖片來實現,相似電影。
定義隨着View狀態而改變的顏色資源。
保存在 res/color/
目錄下,經過 R.color
類來訪問.
定義應用程序使用的圖標資源。
保存在res/mipmap目錄下,經過R.mipmap類來訪問.
定義bitmap圖像或經過XML來定義的圖像資源.
保存在res/drawable/
目錄下,經過R.drawable
類來訪問.
定義應用程序UI的佈局。
保存在res/layout/
目錄下,經過R.layout
類來訪問.
定義應用程序菜單的內容。
保存在res/menu/
目錄下,經過R.menu
類來訪問.
定義串、串數組、和數量字符串(zero, one, two, few, many, other)plurals (而且包含串的格式化以及風格).
保存在res/values/
目錄下,經過R.string
, R.array
, 以及R.plurals
類來訪問.
定義UI元素的外表與格式(look and format).
保存在res/values/
目錄下,經過R.style
類來訪問.
定義諸如布爾值、顏色、維度、ID、整數值、整數數組、TypedArray的值.
保存在res/values/
目錄下,但每一種是經過不一樣的 R
子類(諸如 R.bool
, R.color, R.dimen
, R.id, R.integer
, R.array等)來訪問.
參考資料:
[1] 詳解Android開發中經常使用的 DPI/DP/SP, http://www.jianshu.com/p/913943d25829
[2] 移動開發須要知道的像素知識, http://weizhifeng.net/you-should-know-about-dpi.html
[3] 閒話Android 之 屏幕大小、pixel、分辨率、dpi、dip, http://www.cnblogs.com/zhangxinyan/p/3510604.html
[4] Andriod界面設計的分辨率和尺寸適配全攻略, http://www.25xt.com/appdesign/8693.html
[5] Resource Types, http://developer.android.com/intl/zh-cn/guide/topics/resources/available-resources.html
[6] More Resource Types, http://developer.android.com/intl/zh-cn/guide/topics/resources/more-resources.html
[7] Managing Projects Overview, http://developer.android.com/intl/zh-cn/tools/projects/index.html#ApplicationModules