DP
這個是最常用但也最難理解的尺寸單位。它與“像素密度”密切相關,所以
首先我們解釋一下什么是像素密度。假設有一部手機,屏幕的物理尺寸為1.5英寸x2英寸,屏幕分辨率為240x320,則我們可以計算出在這部手機的屏幕上,
每英寸包含的像素點的數量為240/1.5=160dpi(橫向)或320/2=160dpi(縱向),160dpi就是這部手機的像素密度,像素密度的單位dpi是Dots Per Inch的縮寫,即每英寸像素數量。
橫向和縱向的這個值都是相同的,原因是大部分手機屏幕使用正方形的像素點。
不同的手機/平板可能具有不同的像素密度,例如同為4寸手機,有480x320分辨率的也有800x480分辨率的,前者的像素密度就比較低。
Android系統定義了四種像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi),它們對應的dp到px的系數分別為0.75、1、1.5和2,這個系數乘以dp長度就是像素數。
例如界面上有一個長度為“80dp”的圖片,那么它在240dpi的手機上實際顯示為80x1.5=120px,在320dpi的手機上實際顯示為80x2=160px。
如果你拿這兩部手機放在一起對比,會發現這個圖片的物理尺寸“差不多”,這就是使用dp作為單位的效果
px:
即像素,1px代表屏幕上一個物理的像素點;
px單位不被建議使用,因為同樣100px的圖片,在不同手機上顯示的實際大小可能不同,如下圖所示
dip:
Density independent pixels ,設備無關像素。
與dp完全相同,只是名字不同而已。在早期的Android版本里多使用dip,后來為了與sp統一就建議使用dp這個名字了。
比如一個機器,屏幕4寸,分辨率480X800,他的dpi能算么。
因為不知道邊長,肯定不能分開算,4是對角線長度,那直接用勾股定理算對角線像素,除以4,算出來大概是 dpi = 233 像素/英寸。
那么density就是 (233 px/inch)/(160 px/inch)=1.46 左右
順帶說下,android默認的只有3個dpi,low、medium和high,對應 120、160、240,如果沒有特別設置,所有的dpi都會被算成這3個,具體可以參考下這個帖子
http://android.tgbus.com/Android/tutorial/201103/347176.shtml
其中的default就是160。
sp:
與縮放無關的抽象像素(Scale-independent Pixel)。
sp和dp很類似但唯一的區別是,Android系統允許用戶自定義文字尺寸大小(小、正常、大、超大等等),當文字尺寸是“正常”時1sp=1dp=0.00625英寸,而當文字尺寸是“大”或“超大”時,1sp>1dp=0.00625英寸。
類似我們在windows里調整字體尺寸以后的效果——窗口大小不變,只有文字大小改變。
最佳實踐,文字的尺寸一律用sp單位,非文字的尺寸一律使用dp單位。
例如textSize="16sp"、layout_width="60dp";偶爾需要使用px單位,例如需要在屏幕上畫一條細的分隔線
像素轉換
我們寫布局的時候,肯定還是要知道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,在兩個手機上顯示的大小是一樣的。
所以如果你在App布局中都用的px作為單位,那么你的App跑在各個設備上就會出現奇奇怪怪的現象了。
來看一下emulator上的效果,我定義了兩個Button,分別用px和dip做單位。
布局文件里這樣寫
<Button android:layout_width="100px" android:layout_height="100px" android:text="@string/str_button1"/> <Button android:layout_width="100dip" android:layout_height="100dip" android:text="@string/str_button1"/>