Android度量單位說明(DIP,DP,PX,SP)

(一)概念android

dip: device independent pixels(設備獨立像素). 不一樣設備有不一樣的顯示效果,這個和設備硬件有關,通常咱們爲了支持WVGA、HVGA和QVGA 推薦使用這個,不依賴像素。
px: pixels(像素). 不一樣設備顯示效果相同,通常咱們HVGA表明320x480像素,這個用的比較多。
pt: point,是一個標準的長度單位,1pt=1/72英寸,用於印刷業,很是簡單易用;
sp: scaled pixels(放大像素). 主要用於字體顯示best for textsize。程序員

(二)換算(以 sp 和 pt 爲例)
經過查看TextView 等類的源碼web

case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
--------------------------
scaledDensity = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
xdpi = DENSITY_DEVICE;
--------------------------
DENSITY_DEFAULT = DENSITY_MEDIUM = 160;
函數

因此: 假設 pt 和 sp 取相同的值 1,則可設 1pt 和 1sp 之間係數爲 x,
1 * DENSITY_DEVICE / 72 = x * 1 * DENSITY_DEVICE / 160 =>
x = 160 / 72 = 2.2222佈局

也就是說在 Android 中, 1pt 大概等於 2.22sp字體


(三)關係與區別
this

過去,程序員一般以像素爲單位設計計算機用戶界面。例如,定義一個寬度爲300像素的表單字段,列之間的間距爲5個像素,圖標大小爲16×16像素 等。這樣處理的問題在於,若是在一個每英寸點數(dpi)更高的新顯示器上運行該程序,則用戶界面會顯得很小。在有些狀況下,用戶界面可能會小到難以看清 內容。spa

與分辨率無關的度量單位能夠解決這一問題。Android支持下列全部單位。設計

px(像素):屏幕上的點。code

in(英寸):長度單位。

mm(毫米):長度單位。

pt(磅):1/72英寸。

dp(與密度無關的像素):一種基於屏幕密度的抽象單位。在每英寸160點的顯示器上,1dp = 1px。

dip:與dp相同,多用於android/ophone示例中。
sp(與刻度無關的像素):與dp相似,可是能夠根據用戶的字體大小首選項進行縮放。

(四)建議

爲了使用戶界面可以在如今和未來的顯示器類型上正常顯示,建議你們始終使用sp做爲文字大小的單位,將dip或者dp做爲其餘元素的單位。固然,也能夠考慮使用矢量圖形,而不是用位圖。


基本單位:
 px:像素,是屏幕上顯示數據的最基本的點。
 dp(dip):一種基於屏幕密度的抽象單位(與密度無關的像素)。
 dpi(dots per inch):每英寸所顯示的點數(像素),也可稱爲像素密度。
 pt(磅):是一個標準的長度單位,1pt=1/72英寸,用於印刷業,很是簡單易用。
 sp(與刻度無關的像素):scaled pixels(放大像素). 主要用於字體顯示best for textsize,TextView 的字號可以使用 sp 作單位。

屏幕尺寸Screen size
即顯示屏幕的實際大小,按照屏幕的對角線進行測量。
爲簡單起見,Android把全部的屏幕大小分爲四種尺寸:小,普通,大,超大(分別對應:small, normal, large, and extra large).
應用程序能夠爲這四種尺寸分別提供不一樣的自定義屏幕布局-平臺將根據屏幕實際尺寸選擇對應佈局進行渲染,這種選擇對於程序側是透明的。


密度Density
根據像素分辨率,在屏幕指定物理寬高範圍內能顯示的像素數量。
在一樣的寬高區域,低密度的顯示屏能顯示的像素較少,而高密度的顯示屏則能顯示更多的像素。
屏幕密度很是重要,由於其它條件不變的狀況下,一共寬高固定的UI組件(好比一個按鈕)在在低密度的顯示屏上顯得很大, 而在高密度顯示屏上看起來就很小。
爲簡單起見,Android把全部的屏幕分辨率也分爲四種尺寸:小,普通,大,超大(分別對應:small, normal, large, and extra large).
應用程序能夠爲這四種尺寸分別提供不一樣的資源-平臺將透明的對資源進行縮放以適配指定的屏幕分辨率。




 

獲取屏幕的分辨率
Android 提供 DisplayMetircs類能夠很方便的獲取分辨率,它提供了一種關於顯示的通用信息,如顯示大小,分辨率和字體。 
爲了獲取DisplayMetrics 成員,首先初始化一個對象以下: 

DisplayMetrics metrics = new DisplayMetrics();  
WindowManager WM = (WindowManager)mcontext.getSystemService(Context.WINDOW_SERVICE);
WM.getDefaultDisplay().getMetrics(metrics);

//屏幕的分辨率
int width = dm.widthPixels() ; 
int height = dm.heightPixels();

注:構造函數DisplayMetrics 不須要傳遞任何參數;得到WindowManager 以後, getDefaultDisplay() 方法將取得的默認的顯示信息,返回的是一個Display 對象,此對象的getMetrics(Metrics metrics)方法把分辨率信息傳到 DisplayMetrics 對象中。

經過 DisplayMetrics.toString()方法能夠獲取到 DisplayMetrics的大部分信息,如下是模擬器上不一樣分辨率全部對應的信息: 

QVGA : {density=0.75, width=240, height=320, scaledDensity=0.75, xdpi=120.0, ydpi=120.0}
HVGA : {density=1.0, width=320, height=480, scaledDensity=1.0, xdpi=160.0, ydpi=160.0}
WVGA : {density=1.5, width=480, height=800, scaledDensity=1.5, xdpi=240.0, ydpi=240.0}

其中,density爲顯示的邏輯分辨率;width及height就爲屏幕分辨率(爲絕對寬度與高度),與fields中的widthPixels及 heightPixels一致;scaleDensity與density一致;xdpi及ydpi爲x方向與y方向的像素密度


如何計算密度(dpi)
1.標準是240*320畫在1.5*2平方inch上。那麼像每平方英寸有240*320/(1.5*2)=25600點,也就是一平方英寸的像素點爲25600,因此dpi取爲它的平方根160;若是你的dpi是120,那麼它的密度就是0.75.
2.密度不僅是與width有關,還與height有關,因此無論width是1.8仍是1.3,它的密度都有多是1;好比width是1.8,只要它 的height是3/1.8的話,若是pixel爲240*320的話,它的密度仍舊是1;一樣若是width爲1.3,只要它的 height爲3/1.3的話,像素點爲240*320,則密度也是1.
3.320*480/(1.5*2)獲得單位平方英寸的點爲51200,因此單位平方英寸是240*320畫在1.5*2屏幕的2倍。可是這是平方英寸啊,算密度的時候要開平方的啊,因此應該是2開平方,是1.414吧,大體密度爲1.5。


px與dip的關係:
Android中,在160dpi (mdpi)中, 1 dip= 1 px;
以此類推,在120dpi(ldpi)中, 1 dip = 0.75px;
                 在240dpi (hdpi)中, 1 dip = 1.5px;
                 在320dpi(xhdpi)中, 1dip = 2px;


如何作到與密度無關:
  若是屏幕密度爲160,這時dp和sp和px是同樣的。1dp=1sp=1px,但若是使用px做單位,若是屏幕大小不變(假設仍是3.2寸),而屏幕密度變成了320。那麼原來TextView的寬度設成160px,在密度爲320的3.2 寸屏幕裏看要比在密度爲160的3.2寸屏幕上看短了一半。但若是設置成160dp或160sp的話。系統會自動將width屬性值設置成320px的。也就是160 * 320 / 160。其中320 / 160可稱爲密度比例因子。也就是說,若是使用dp和sp,系統會根據屏幕密度的變化自動進行轉換。官方文檔總結的計算公式爲:pixels = dps * (density /160).
使用dip做爲View的單位,這樣就能夠同時兼容各類不一樣的分辨率,不會形成UI的不可兼容。


使用dip做爲控件的大小單位:
    1.佈局文件:
       若是使用佈局文件的形式定義控件,可直接在 android:layout_width 和 android:layout_height 中使用dip做爲單位,來定義View的大 小,以下:
       <TextView android:layout_width="50dip" android:layout_height="50dip"></TextView>

   2.代碼形式:
      若是是自定義的View控件,那麼可能使用的是代碼的形式來佈局,好比:
       MyTextView myTextView = new MyTextView(this);
       能夠調用myTextView.setWidth() 和 setHeight()來設置View寬度和高度,可是這兩個方法接收的是以像素單位的值,也就說,若是要用代碼的形式來以dip爲單位設置View大小,則須要先將dip轉換爲px。
       這裏可使用以下方法,以下:

 [object Object]public static int px2dip(Context context, float pxValue) {
 [object Object]final float scale = context.getResources().getDisplayMetrics().density ; 

         return (int) (pxValue / scale + 0.5f) ; 
}

 

 public static int dip2px(Context context, float dpValue) { 

         final float scale = context.getResources().getDisplayMetrics().density ; 

         return (int) (dpValue * scale + 0.5f) ;
 [object Object]}
 [object Object]將dip數值轉換爲px後,在調用setWidth() 和setHeight()來設置View寬度和高度。 
當在屏幕爲160dpi,也就是density爲1的狀況下,所獲得的控件的寬度和高度爲android控件的默認的dip大小。
好比:Button 的 默認高度爲 48dip。

          狀態欄的默認高度爲25dip。
相關文章
相關標籤/搜索