px :是螢幕的畫素點
in :英寸
mm :毫米
pt :磅,1/72 英寸
dp :一個基於density的抽象單位,如果一個160dpi的螢幕,1dp=1px
dip :等同於dp
sp :同dp相似,但還會根據使用者的字型大小偏好來縮放。
建議使用sp作為文字的單位,其它用dip
針對dip和px 的關係,做以下概述:
下面是一些解析度資訊 density就是螢幕密度
名稱 | 解析度 | 螢幕密度 |
QVGA | 320*240 | 120 |
WQVGA400 | 400*240 | 120 |
WQVGA432 | 432*240 | 120 |
HVGA | 640*480 | 160 |
WSVGA | 1024*600 | 160 |
WXGA800 | 1280*800 | 160 |
WVGA800 | 800*480 | 240 |
WVGA854 | 854*480 | 240 |
WXGA720 | 1280*720 | 320 |
density值表示每英寸有多少個顯示點,與解析度是兩個概念。
不同density下螢幕解析度資訊,以480dip*800dip的 WVGA(density=240)為例
下面以幾個真實機器來加深一下相關概念的認知
三星i5801 | HTC wildfire S(g13) | HTC sensation(g14) | meizu m9 | |
---|---|---|---|---|
解析度 | 240*400 | 320*480 | 540*960 | 640*960 |
螢幕尺寸 | 3.2英寸 | 3.2英寸 | 4.3英寸 | 3.5英寸 |
螢幕密度 | 145.77 | 180.27 | 256.15 | 329.65 |
DisplayMetrics得出的DPI | 120 | 160 | 240 | 320 |
黃色部分為使用上述公式計算的螢幕密度,綠色部分為使用DisplayMetrics得出的dpi,可以看到比較接近
有兩方面的原因,導致這兩個資料不一致
1.廠商給出的螢幕尺寸引數不是太精確
2.DisplayMetrics中定義的密度值只有120、160、213、240、320
----------------------------------------
這裡從另一個角度可以進行螢幕尺寸的反推,以meizu m9為例,通過DisplayMetrics可以得到其xdpi和ydpi均為325.12
這樣螢幕寬度=640/325.12=1.9685英寸,螢幕高度=960/325.12=2.9527英寸
使用勾股定理計算得出,對角線尺寸為3.5487英寸
density=120時
螢幕實際解析度為240px*400px (兩個點對應一個解析度)
狀態列和標題欄高各19px或者25dip
橫屏是螢幕寬度400px 或者800dip,工作區域高度211px或者480dip
豎屏時螢幕寬度240px或者480dip,工作區域高度381px或者775dip
density=160時
螢幕實際解析度為320px*533px (3個點對應兩個解析度)
狀態列和標題欄高個25px或者25dip
橫屏是螢幕寬度533px 或者800dip,工作區域高度295px或者480dip
豎屏時螢幕寬度320px或者480dip,工作區域高度508px或者775dip
density=240時
螢幕實際解析度為480px*800px (一個點對於一個解析度)
狀態列和標題欄高個38px或者25dip
橫屏是螢幕寬度800px 或者800dip,工作區域高度442px或者480dip
豎屏時螢幕寬度480px或者480dip,工作區域高度762px或者775dip
apk的資源包中
當螢幕density=240時,使用hdpi 標籤的資源
當螢幕density=160時,使用mdpi標籤的資源
當螢幕density=120時,使用ldpi標籤的資源。
不加任何標籤的資源是各種解析度情況下共用的。
佈局時儘量使用單位dip,少使用px
dp與px換算公式:
pixs =dips * (densityDpi/160).
dips=(pixs*160)/densityDpi
dp與px轉換的方法:
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.getResource().getDisplayMetrics().density;
return (int)(pxValue / scale +0.5f);
}
名詞 |
解釋 |
Px (Pixel畫素) |
不同裝置顯示效果相同。這裡的“相同”是指畫素數不會變,比如指定UI長度是100px,那不管解析度是多少UI長度都是100px。也正是因為如此才造成了UI在小解析度裝置上被放大而失真,在大解析度上被縮小。 |
Screen Size (螢幕尺寸) |
一般所說的手機螢幕大小如1.6英寸、1.9英寸、2.2英寸,都是指的對角線的長度,而不是手機面積。我們可以根據勾股定理獲取手機的寬和長,當然還有面積。 |
Resolution (解析度) |
指手機螢幕垂直和水平方向上的畫素個數。比如解析度是480*320,則指裝置垂直方向有480個畫素點,水平方向有320個畫素點。 |
Dpi (dots per inch 畫素密度) |
指每英寸中的畫素數。如160dpi指手機水平或垂直方向上每英寸距離有160個畫素點。假定裝置解析度為320*240,螢幕長2英寸寬1.5英寸,dpi=320/2=240/1.5=160 注意:該值對應於DisplayMetrics類中屬性densityDpi的值 |
Density (密度) |
指每平方英寸中的畫素數。 Density=Resolution/Screen size 注意:在DisplayMetrics類中屬性density的值為dpi/160,可用於px與dip的互相轉換 |
Dip (Device-independent pixel,裝置獨立畫素) |
同dp,可作長度單位,不同裝置有不同的顯示效果,這個和裝置硬體有關,一般我們為了支援WVGA、HVGA和QVGA 推薦使用這個,不依賴畫素。dip和具體畫素值的對應公式是dip值 =裝置密度/160* pixel值,可以看出在dpi(畫素密度)為160dpi的裝置上1px=1dip |
Sp (ScaledPixels 放大畫素) |
主要用於字型顯示(best for textsize)。根據 google 的建議,TextView 的字號最好使用 sp 做單位,而且檢視TextView的原始碼可知 Android 預設使用 sp 作為字號單位。 |