前言
首先要說的是,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,在兩個手機上顯示的大小是一樣的。
關於更多
相信自己,沒有做不到的,只有想不到的
微信公眾號:終端研發部