px、dp和sp,這些單位有什麼區別?

DPhtml

這個是最經常使用但也最難理解的尺寸單位。它與「像素密度」密切相關,因此android

首先咱們解釋一下什麼是像素密度。假設有一部手機,屏幕的物理尺寸爲1.5英寸x2英寸,屏幕分辨率爲240x320,則咱們能夠計算出在這部手機的屏幕上,windows

每英寸包含的像素點的數量爲240/1.5=160dpi(橫向)或320/2=160dpi(縱向),160dpi就是這部手機的像素密度,像素密度的單位dpi是Dots Per Inch的縮寫,即每英寸像素數量。佈局

橫向和縱向的這個值都是相同的,緣由是大部分手機屏幕使用正方形的像素點。字體

不一樣的手機/平板可能具備不一樣的像素密度,例如同爲4寸手機,有480x320分辨率的也有800x480分辨率的,前者的像素密度就比較低。spa

Android系統定義了四種像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi),它們對應的dp到px的係數分別爲0.7五、一、1.5和2,這個係數乘以dp長度就是像素數。設計

例如界面上有一個長度爲「80dp」的圖片,那麼它在240dpi的手機上實際顯示爲80x1.5=120px,在320dpi的手機上實際顯示爲80x2=160px。3d

若是你拿這兩部手機放在一塊兒對比,會發現這個圖片的物理尺寸「差很少」,這就是使用dp做爲單位的效果code

 

px:

即像素,1px表明屏幕上一個物理的像素點;htm

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"/>
相關文章
相關標籤/搜索