參考鏈接 http://www.reibang.com/p/913943d25829
Android的碎片化已經(jīng)被噴了好多年然眼,隨著國內(nèi)手機廠商的崛起汉柒,碎片化也越來越嚴(yán)重矛洞,根據(jù)OpenSignal的最新調(diào)查眠菇,2014年市面上有18796種不同的Android設(shè)備畏邢,作為開發(fā)者剂跟,一個無法回避的難題就是需要適配各種各樣奇奇怪怪的機型减途。
設(shè)備機型不同必然也會導(dǎo)致屏幕大小和分辨率(Resolution)的不同,但是無論分辨率有多大曹洽,屏幕有多大鳍置,我們手指觸控范圍的大小不會發(fā)生變化,所以最優(yōu)的適配方式應(yīng)該是指定大小的控件在所有的設(shè)備上的顯示都一樣送淆。
Android的官方文檔對此也有明確的說明
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.
所以税产,適配應(yīng)該與分辨率無關(guān),只與屏幕大小和屏幕密度相關(guān),首先來看一下什么是屏幕密度 - DPI辟拷。
DPI
DPI的全稱是 Dots Per Inch撞羽,Inch是一個物理單位(無論在任何設(shè)備上,其大小都是固定的)衫冻,所以DPI就指在一個Inch的物理長度內(nèi)有多少個Dot诀紊,160DPI的屏幕就表示一個Inch包含160個Dot,320DPI的屏幕表示一個Inch有320個Dot隅俘,所以說Dot的大小是不固定的邻奠。
Android設(shè)備用DPI來表示屏幕密度(Density),屏幕密度大就表示一個Inch包含的Dot比較多考赛。那PPI是什么呢惕澎?
我們會經(jīng)常看到iPad颜骤、iPhone是用PPI來表示屏幕密度唧喉,小米Pad也是用PPI來表示。
其實對Android而言忍抽,DPI等價于PPI(Pixels-Per-Inch)八孝,DPI最早是用于印刷行業(yè),跟PPI還是有本質(zhì)不同的鸠项,Android應(yīng)該是誤用了DPI這個概念干跛。具體可以參考PPI vs. DPI: what’s the difference?。
其實我們只要知道在Android設(shè)備中祟绊,DPI 等價于 PPI 就可以了楼入。
通常我們說一個設(shè)備是多少寸時,指的是屏幕對角線(Diagonal)是多少inch牧抽,所以用對角線的像素值(px)除以對角線長度(inch)嘉熊,就可以計算出PPI。
為了簡化適配工作扬舒,Android根據(jù)屏幕大胁簟(Inch)和屏幕密度(DPI)對設(shè)備做了如下劃分:
DP
既然有那么多不同分辨率、不同大小的屏幕讲坎,使用PX必然會導(dǎo)致適配困難孕惜,為了進一步簡化適配工作,Android為我們提供了一個虛擬的像素單位 - DP 或者 DIP (Density-Independent pixel)晨炕,當(dāng)然也可以理解為 Device-Independent Pixel衫画。為什么說是虛擬呢,因為它的大小不是一個物理(Phisical)值瓮栗,而是由操作系統(tǒng)根據(jù)屏幕大小和密度動態(tài)渲染出來的碧磅。
PX跟DP之間的換算關(guān)系很簡單
px = dp * (dpi / 160)
舉例來說碘箍,小米Pad的屏幕密度為326dpi,如果需要顯示的圖片大小為20dp鲸郊,那么就需要提供一個 20 _(326 / 160) = 40px_
的圖片才能達到最佳顯示效果丰榴,如果還要適配一個163dpi的屏幕,那么還需要再提供一個20 (163 / 160) = 20px
的圖片秆撮。
那么一個20dp的圖片四濒,在不同設(shè)備上的顯示效果如何呢?我們以iPad為例來說明职辨。
iPad2 和 iPad Retina的物理尺寸都是 9.7 inch盗蟆,不同的是分辨率和PPI,一個是1024x768 / 132ppi舒裤,另一個是2048x1536 / 264ppi喳资,
分別計算一下20dp對應(yīng)多少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)))
計算結(jié)果都是0.1018359375,這就是dp的功能腾供,它能保證在所有的設(shè)備上顯示的大小都一樣仆邓。
如果只提供了一個大小為20px的圖片,為了保證圖片在所有設(shè)備上的物理大小都一樣伴鳖,高DPI的設(shè)備上系統(tǒng)會拉伸圖片节值,低DPI的設(shè)備上圖片會被縮小,這樣既會影響UE也會影響APP的執(zhí)行效率榜聂。所以我們需要為不同屏幕密度的設(shè)備提供不同的圖片搞疗,他們之間的對應(yīng)關(guān)系如下。
我們在用Sketch作圖的時候须肆,如果1x圖片對應(yīng)的是屏幕是MDPI (160dpi)匿乃,那么1.5x,2x就分別對應(yīng)HDPI豌汇,XHDPI扳埂。
SP
SP 全稱是 Scale-independent Pixels,用于字體大小瘤礁,其概念與DP是一致的,也是為了保持設(shè)備無關(guān)梅尤。因為Android用戶可以根據(jù)喜好來調(diào)整字體大小柜思,所以要使用sp來表示字體大小。
參考文獻
- http://developer.android.com/guide/practices/screens_support.html#DeclaringTabletLayouts
- http://developer.android.com/training/multiscreen/screendensities.html
- http://stackoverflow.com/questions/2025282/difference-between-px-dp-dip-and-sp-in-android
- http://99designs.com/designer-blog/2013/02/26/ppi-vs-dpi-whats-the-difference/