詳解Android開發中常用的 DPI / DP / SP

jopen 9年前發布 | 79K 次閱讀 Android Android開發 移動開發

Android的碎片化已經被噴了好多年,隨著國內手機廠商的崛起,碎片化也越來越嚴重,根據OpenSignal的最新調查,2014年市面上有18796種不同的Android設備,作為開發者,一個無法回避的難題就是需要適配各種各樣奇奇怪怪的機型。

設備機型不同必然也會導致屏幕大小和分辨率(Resolution)的不同,但是無論分辨率有多大,屏幕有多大,我們手指觸控范圍的大小不會發生變化,所以最優的適配方式應該是指定大小的控件在所有的設備上的顯示都一樣

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.

</blockquote>

所以,適配應該與分辨率無關,只與屏幕大小和屏幕密度相關,首先來看一下什么是屏幕密度 - DPI。

DPI

DPI的全稱是 Dots Per Inch,Inch是一個物理單位(無論在任何設備上,其大小都是固定的),所以DPI就指在一個Inch的物理長度內有多少個Dot,160DPI的屏 幕就表示一個Inch包含160個Dot,320DPI的屏幕表示一個Inch有320個Dot,所以說Dot的大小是不固定的。

Android設備用DPI來表示屏幕密度(Density),屏幕密度大就表示一個Inch包含的Dot比較多。那PPI是什么呢?
我們會經常看到iPad、iPhone是用PPI來表示屏幕密度,小米Pad也是用PPI來表示。


PPI in mi pad
</div>

其實對Android而言,DPI等價于PPI(Pixels-Per-Inch),DPI最早是用于印刷行業,跟PPI還是有本質不同的,Android應該是誤用了DPI這個概念。具體可以參考PPI vs. DPI: what’s the difference?

其實我們只要知道在Android設備中,DPI 等價于 PPI 就可以了。


PPI 定義
</div>

通常我們說一個設備是多少寸時,指的是屏幕對角線(Diagonal)是多少inch,所以用對角線的像素值(px)除以對角線長度(inch),就可以計算出PPI。


PPI 計算公式
</div>

為了簡化適配工作,Android根據屏幕大小(Inch)和屏幕密度(DPI)對設備做了如下劃分:


PPI 對應屏幕尺寸
</div>

DP

既然有那么多不同分辨率、不同大小的屏幕,使用PX必然會導致適配困難,為了進一步簡化適配工作,Android為我們提供了一個虛擬的像素單位 - DP 或者 DIP (Density-Independent pixel),當然也可以理解為 Device-Independent Pixel。為什么說是虛擬呢,因為它的大小不是一個物理(Phisical)值,而是由操作系統根據屏幕大小和密度動態渲染出來的。

PX跟DP之間的換算關系很簡單

px = dp * (dpi / 160)

</blockquote>

舉例來說,小米Pad的屏幕密度為326dpi,如果需要顯示的圖片大小為20dp,那么就需要提供一個20 (326 / 160) = 40px的圖片才能達到最佳顯示效果,如果還要適配一個163dpi的屏幕,那么還需要再提供一個20 (163 / 160) = 20px的圖片。

那么一個20dp的圖片,在不同設備上的顯示效果如何呢?我們以iPad為例來說明。


iPad 屏幕參數
</div>

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的功能,它能保證在所有的設備上顯示的大小都一樣。

如果只提供了一個大小為20px的圖片,為了保證圖片在所有設備上的物理大小都一樣,高DPI的設備上系統會拉伸圖片,低DPI的設備上圖片會被縮小,這樣既會影響UE也會影響APP的執行效率。所以我們需要為不同屏幕密度的設備提供不同的圖片,他們之間的對應關系如下。


Android 設備屏幕分級
</div>

我們在用Sketch作圖的時候,如果1x圖片對應的是屏幕是MDPI (160dpi),那么1.5x,2x就分別對應HDPI,XHDPI。


screens_densities
</div>

SP

SP 全稱是 Scale-independent Pixels,用于字體大小,其概念與DP是一致的,也是為了保持設備無關。因為Android用戶可以根據喜好來調整字體大小,所以要使用sp來表示字體大小。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!