在處理 UI 部份的大小, 位置, 等數據時, 要特別留心用到的是什麼單位.
pt: (Points)
1/72 of an inch based on the physical size of the screen.
每一英吋需要畫幾個點.
px: (Pixel)
corresponds to actual pixels on the screen.
實際上螢幕上顯示的一個點.
mm: (millimeters)
公分
in: (inches)
英吋
以上這些都很簡單直覺, 實在是沒有什麼需要說明的.
真正比較複雜的, 是 dp/dip/sp. 在這之前, 先說明一下 Density Bucket:
Density Bucket
Android
把螢幕的解析分成以下幾個等級, 稱為 Density Bucket,從以的表格, 可以了解到, Android 在顯示到螢幕輸出的時候, 會根據目前實際所需要的輸出, 把圖片做放大縮小, 這樣當我們需要顯示一個 0.5 英吋平方的圖案時, 就可以在大多數的輸出裝置看到大小相近的圖案. 雖然圖案的細節可能有差異 (圖案內容精細與否), 但大小是相仿的. 同時, 對於這些不同的 Density Bucket, 設計者也可以使用不同的 resource 檔案,
針對各不同的 Density Bucket 去做優化.
Density Bucket Name
|
Density Bucket
|
Screen Density
|
Ratio
|
Scaler
|
Low
|
ldpi
|
120 dpi
|
3
|
0.75
|
Medium
|
mdpi
|
160 dpi
|
4
|
1.00
|
TV
|
tvdpi
|
213 dpi
|
5.325
|
1.33
|
High
|
hdpi
|
240 dpi
|
6
|
1.50
|
Extra High
|
xhdpi
|
320 dpi
|
8
|
2.00
|
Extra Extra High
|
xxhdpi
|
480 dpi
|
12
|
3.00
|
dp/dip (density independent pixel) 是會經過 Density Bucket 做放大縮小的單位, sp則是會再套用使用者的字型單位.
下面這個表格, 可以進一步的說明 dp/dip 是什麼
Device Density
|
Density Bucket
|
# of dp
|
Scaling Factor
|
Physical Size
|
232 dpi
|
hdpi-240 dpi
|
100 dp
|
1.5 px/dp
|
150 px/232 dpi = 0.647 in
|
240 dpi
|
hdpi-240 dpi
|
100 dp
|
1.5 px/dp
|
150 px/240 dpi = 0.625 in
|
263 dpi
|
hdpi-240 dpi
|
100 dp
|
1.5 px/dp
|
150 px/263 dpi = 0.570 in
|
314 dpi
|
xhdpi-320 dpi
|
100 dp
|
2.0 px/dp
|
200 px/314 dpi = 0.637 in
|
320 dpi
|
xhdpi-320 dpi
|
100 dp
|
2.0 px/dp
|
200 px/320 dpi = 0.625 in
|
336 dpi
|
xhdpi-320 dpi
|
100 dp
|
2.0 px/dp
|
200 px/336 dpi = 0.595 in
|
換句話說, 不管 device 的螢幕大小, 精細程度, 指定同樣的 dp (dip) , 在不同的 device 上, 看到的大小也是相仿的.
那如果顯示的結果佔畫面的1/2 或是成比例呢 ? 這時候就不要用 dp/dip 了, 取得螢幕的實際大小, 用 px (pixel ) 去換算, 說不定比較快 (可以參考以下程式碼).
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
screen_width = metrics.widthPixels;
screen_height = metrics.heightPixels;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
screen_width = metrics.widthPixels;
screen_height = metrics.heightPixels;