什麼是dp,dip,sp和px及他們之間的的關係?《二》

codeGoogle發表於2018-01-25

前言

首先要說的是,Android的碎片化的問題非常嚴重。因為 Android廠商非常多,裝置非常多,產生了各種各樣的解析度。 為了解決碎片化的問題,Android 開發文件中定義了 dp,sp 等新的單位

相關概念

  • dip: device independent pixels(裝置獨立畫素) 不同裝置有不同的顯示效果,這個和裝置硬體有關,一般我們為了支援WVGA、HVGA和QVGA 推薦使用這 這個,不依賴畫素。

    這裡要特別注意dip與螢幕密度有關,而螢幕密度又與具體的硬體有關,硬體設定不正確,有可能導致dip不能正常顯示。在螢幕密度為160的螢幕上,1dip=1px,有時候可能你的螢幕解析度很大如480*800,但是螢幕密度沒有正確設定比如說還是160,那麼這個時候凡是使用dip的都會顯示異常,基本都是顯示過小。

    dip的換算: dip(value)=(int) (px(value)/1.5 + 0.5)

  • dp: 很簡單,和dip是一樣的。

  • px:px是夠長圖片的最小單位。 pixels(畫素),不同的裝置不同的螢幕顯示效果是相同的,這是絕對畫素,是多少就永遠是多少不會改變。

  • sp: scaled pixels(放大畫素). 主要用於字型顯示best for textsize。

更多瞭解: https://www.cnblogs.com/wangjiafang/p/4433912.html

常見手機螢幕畫素及對應分別率級別:

分別率級別 密度
ldpi 320*240
mdpi 480*320
hdpi 800*480
xhdpi 1280*720
xxhdpi 1920*1080

dp 和 px 之間的簡單換算關係:

分別率級別 換算關係
ldpi 的手機 1dp=0.75px
mdpi 的手機 1dp=1.0px
hdpi 的手機 1dp=1.5px
xhdpi 的手機 1dp=2.0px
xxhdpi 的手機 1dp=3.0px

不同手機,不同解析度的顯示效果

Tip:根據上面的描述我們得出如下結論,對於 mdpi 的手機,我們的佈局通過 dp 單位可以達到適 配效果

舉個栗子:

假設有一個QVGA(320x480)解析度的螢幕物理尺寸是2英寸*1.5英寸,則這部手機的dpi=160 Screen Size指的是手機實際的物理尺寸,如iPhone4S是3.5英寸,這裡的3.5英寸指的是手機螢幕對角線的長度為3.5英寸。

注意: 我們在使用的時候,畫素統一使用dip,字型統一使用sp。例如textSize="16sp"、layout_width="60dp";偶爾需要使用px單位,例如需要在螢幕上畫一條細的分隔線時. 這樣也是google的推薦建議。

轉換

public static int dip2px(Context context, float dipValue){ 
                final float scale = context.getResources().getDisplayMetrics().density; 
                return (int)(dipValue * scale + 0.5f); 
        } 
        
    public static int px2dip(Context context, float pxValue){ 
                final float scale = context.getResources().getDisplayMetrics().density; 
                return (int)(pxValue / scale + 0.5f); 
        } 
複製程式碼

畫素轉換

我們寫佈局的時候,肯定還是要知道1個dp到底有多少px的。

  換算公式如下: dp = (DPI/(160畫素/英寸))px = density px

  注意,這裡都是帶單位的。px是單位,dp是單位,density沒單位。

  為了方便,假設dpi是240 畫素/英寸 , 那麼density就是1.5

  那麼就是 dp=1.5px ,注意這是帶了單位的,也就是 裝置無關畫素 = density 畫素

  那麼轉換為數值計算的話,應該是下面這個式子

  PX = density * DP

也就是   畫素值 = density * 裝置無關畫素值 ,請注意這裡有個值字。

為啥 標準dpi = 160

  (1)Android Design [1] 裡把主流裝置的 dpi 歸成了四個檔次,120 dpi、160 dpi、240 dpi、320 dpi

  實際開發當中,我們經常需要對這幾個尺寸進行相互轉換(比如先在某個解析度下完成設計,然後縮放到其他尺寸微調後輸出),一般按照 dpi 之間的比例即 2:1.5:1:0.75   來給介面中的元素來進行尺寸定義。

  也就是說如果以 160 dpi 作為基準的話,只要尺寸的 DP 是 4 的公倍數,XHDPI 下乘以 2,HDPI 下乘以 1.5,LDPI 下乘以 0.75 即可滿足所有尺寸下都是整數 pixel 。

  但假設以 240 dpi 作為標準,那需要 DP 是 3 的公倍數,XHDPI 下乘以 1.333,MDPI 下乘以 0.666 ,LDPI 下除以 2

  而以 LDPI 和 XHDPI 為基準就更復雜了,所以選擇 160 dpi

 (2)這個在Google的官方文件中有給出瞭解釋,因為第一款Android裝置(HTC的T-Mobile G1)是屬於160dpi的。
複製程式碼

為什麼我們在佈局的時候最好要用dip,不要用px?

  是因為這個世界上存在著很多不同螢幕密度的手機,螢幕密度是什麼?就是dpi,就是單位長度裡的畫素數量。

  想象一下,如果這些手機的尺寸一樣,螢幕密度相差很大,那麼是不是說一個手機水平方向上畫素很少,另一個手機水平方向上畫素很多?那我們畫同樣pix數量的時候,它顯

  示的長度不就會不一樣了?

  比如下面圖中的兩個手機,同時設定2px長度的Button,在螢幕密度較高的手機裡就會顯示的比較小。

  而同時設定的2dip長度的Button,在兩個手機上顯示的大小是一樣的。   

  

關於更多

螢幕適配之尺寸的相關概論《一》

破解Android版微信跳一跳,一招教你挑戰高分

記一次阿里面試經歷|Java面試知識整理

NDK專案實戰—高仿360手機助手之解除安裝監聽

相信自己,沒有做不到的,只有想不到的

微信公眾號:終端研發部

技術+職場

相關文章