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


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"/>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM