px、dp和sp,這些單位有什么區(qū)別?
px、dp和sp,這些單位有什么區(qū)別?
DP
這個(gè)是最常用但也最難理解的尺寸單位。它與“像素密度”密切相關(guān),所以
首先我們解釋一下什么是像素密度。假設(shè)有一部手機(jī),屏幕的物理尺寸為1.5英寸x2英寸,屏幕分辨率為240x320,則我們可以計(jì)算出在這部手機(jī)的屏幕上,
每英寸包含的像素點(diǎn)的數(shù)量為240/1.5=160dpi(橫向)或320/2=160dpi(縱向),160dpi就是這部手機(jī)的像素密度,像素密度的單位dpi是Dots Per Inch的縮寫,即每英寸像素?cái)?shù)量。
橫向和縱向的這個(gè)值都是相同的,原因是大部分手機(jī)屏幕使用正方形的像素點(diǎn)。
不同的手機(jī)/平板可能具有不同的像素密度,例如同為4寸手機(jī),有480x320分辨率的也有800x480分辨率的,前者的像素密度就比較低。
Android系統(tǒng)定義了四種像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi),它們對(duì)應(yīng)的dp到px的系數(shù)分別為0.75、1、1.5和2,這個(gè)系數(shù)乘以dp長度就是像素?cái)?shù)。
例如界面上有一個(gè)長度為“80dp”的圖片,那么它在240dpi的手機(jī)上實(shí)際顯示為80x1.5=120px,在320dpi的手機(jī)上實(shí)際顯示為80x2=160px。
如果你拿這兩部手機(jī)放在一起對(duì)比,會(huì)發(fā)現(xiàn)這個(gè)圖片的物理尺寸“差不多”,這就是使用dp作為單位的效果

px:
即像素,1px代表屏幕上一個(gè)物理的像素點(diǎn);
px單位不被建議使用,因?yàn)橥瑯?00px的圖片,在不同手機(jī)上顯示的實(shí)際大小可能不同,如下圖所示

dip:
Density independent pixels ,設(shè)備無關(guān)像素。
與dp完全相同,只是名字不同而已。在早期的Android版本里多使用dip,后來為了與sp統(tǒng)一就建議使用dp這個(gè)名字了。
比如一個(gè)機(jī)器,屏幕4寸,分辨率480X800,他的dpi能算么。
因?yàn)椴恢肋呴L,肯定不能分開算,4是對(duì)角線長度,那直接用勾股定理算對(duì)角線像素,除以4,算出來大概是 dpi = 233 像素/英寸。
那么density就是 (233 px/inch)/(160 px/inch)=1.46 左右
順帶說下,android默認(rèn)的只有3個(gè)dpi,low、medium和high,對(duì)應(yīng) 120、160、240,如果沒有特別設(shè)置,所有的dpi都會(huì)被算成這3個(gè),具體可以參考下這個(gè)帖子
http://android.tgbus.com/Android/tutorial/201103/347176.shtml
其中的default就是160。
sp:
與縮放無關(guān)的抽象像素(Scale-independent Pixel)。
sp和dp很類似但唯一的區(qū)別是,Android系統(tǒng)允許用戶自定義文字尺寸大?。ㄐ?、正常、大、超大等等),當(dāng)文字尺寸是“正?!睍r(shí)1sp=1dp=0.00625英寸,而當(dāng)文字尺寸是“大”或“超大”時(shí),1sp>1dp=0.00625英寸。
類似我們?cè)趙indows里調(diào)整字體尺寸以后的效果——窗口大小不變,只有文字大小改變。
最佳實(shí)踐,文字的尺寸一律用sp單位,非文字的尺寸一律使用dp單位。
例如textSize="16sp"、layout_width="60dp";偶爾需要使用px單位,例如需要在屏幕上畫一條細(xì)的分隔線
像素轉(zhuǎn)換
我們寫布局的時(shí)候,肯定還是要知道1個(gè)dp到底有多少px的。
換算公式如下: dp = (DPI/(160像素/英寸))px = density px
注意,這里都是帶單位的。px是單位,dp是單位,density沒單位。
為了方便,假設(shè)dpi是240 像素/英寸 , 那么density就是1.5
那么就是 dp=1.5px ,注意這是帶了單位的,也就是 設(shè)備無關(guān)像素 = density 像素
那么轉(zhuǎn)換為數(shù)值計(jì)算的話,應(yīng)該是下面這個(gè)式子
PX = density * DP
也就是
像素值 = density * 設(shè)備無關(guān)像素值 ,請(qǐng)注意這里有個(gè)值字。
為啥 標(biāo)準(zhǔn)dpi = 160
?。?)Android Design [1] 里把主流設(shè)備的 dpi 歸成了四個(gè)檔次,120 dpi、160 dpi、240 dpi、320 dpi
實(shí)際開發(fā)當(dāng)中,我們經(jīng)常需要對(duì)這幾個(gè)尺寸進(jìn)行相互轉(zhuǎn)換(比如先在某個(gè)分辨率下完成設(shè)計(jì),然后縮放到其他尺寸微調(diào)后輸出),一般按照 dpi 之間的比例即 2:1.5:1:0.75 來給界面中的元素來進(jìn)行尺寸定義。
也就是說如果以 160 dpi 作為基準(zhǔn)的話,只要尺寸的 DP 是 4 的公倍數(shù),XHDPI 下乘以 2,HDPI 下乘以 1.5,LDPI 下乘以 0.75 即可滿足所有尺寸下都是整數(shù) pixel 。
但假設(shè)以 240 dpi 作為標(biāo)準(zhǔn),那需要 DP 是 3 的公倍數(shù),XHDPI 下乘以 1.333,MDPI 下乘以 0.666 ,LDPI 下除以 2
而以 LDPI 和 XHDPI 為基準(zhǔn)就更復(fù)雜了,所以選擇 160 dpi
(2)這個(gè)在Google的官方文檔中有給出了解釋,因?yàn)榈谝豢預(yù)ndroid設(shè)備(HTC的T-Mobile G1)是屬于160dpi的。
為什么我們?cè)诓季值臅r(shí)候最好要用dip,不要用px?
是因?yàn)檫@個(gè)世界上存在著很多不同屏幕密度的手機(jī),屏幕密度是什么?就是dpi,就是單位長度里的像素?cái)?shù)量。
想象一下,如果這些手機(jī)的尺寸一樣,屏幕密度相差很大,那么是不是說一個(gè)手機(jī)水平方向上像素很少,另一個(gè)手機(jī)水平方向上像素很多?那我們畫同樣pix數(shù)量的時(shí)候,它顯
示的長度不就會(huì)不一樣了?
比如下面圖中的兩個(gè)手機(jī),同時(shí)設(shè)置2px長度的Button,在屏幕密度較高的手機(jī)里就會(huì)顯示的比較小。
而同時(shí)設(shè)置的2dip長度的Button,在兩個(gè)手機(jī)上顯示的大小是一樣的。

所以如果你在App布局中都用的px作為單位,那么你的App跑在各個(gè)設(shè)備上就會(huì)出現(xiàn)奇奇怪怪的現(xiàn)象了。
來看一下emulator上的效果,我定義了兩個(gè)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"/>


































