Android開發之dp

     關於Android的dp和sp單位,相信大家一定有很多疑問?下面的答案直接來自本人在知乎的回答。出處:http://www.zhihu.com/question/20697111/answer/22722671
1.在Xdpi下繪製Xpx長度,實際的物理距離都是1英寸,爲什麼一定要選160呢?
答:這個在Google的官方文檔中有給出瞭解釋,因爲第一款Android設備(HTC的T-Mobile G1)是屬於160dpi的。
The generalized sizes and densities are arranged around a baseline configuration that is a normal size and mdpi(medium) density. This baseline is based upon the screen configuration for the first Android-powered device, the T-Mobile G1, which has an HVGA screen (until Android 1.6, this was the only screen configuration that Android supported).
爲什麼說是屬於呢?
因爲我查過T-Mobile G1的DPI,其實它準確的DPI不等於160,G1的配置信息如下:
  • 屏幕尺寸:3.2 寸(8.1 釐米)
  • 分辨率:320 x 480(HVGA)
在計算DPI前我先簡單介紹一下DPI以及相關概念,DPI(Dots Per Inch)翻譯爲每英寸像素點的個數,英寸是一個物理單位,1英寸 = 2.54釐米,大家平常說的手機屏幕4.3英寸,4.5英寸指的是屏幕對角線的長度,如下圖所示:
分辨率480 x 800,屏幕尺寸4.3英寸和分辨率540 x 960,屏幕尺寸4.5英寸的DPI分別是:
如果按照這樣的計算方式的話,T-Mobile G1應該爲180dpi,這個計算大家可以使用計算器或者手動的計算方式得出,爲了更具說服力,我貼出自己的計算截圖(使用DPI Caculator計算)
大家可以看到計算出來的結果是180而不是160,大家會想那爲什麼不直接用180作爲基準(mdpi)而是160呢?這就好像爲什麼是二進制而不是其他進制,就像@JJ Ying說的,180上下不好做適配,但是160無論是乘以0.5/2/1.5都很好適配,這就是爲什麼我說屬於而不是等於,Android其實爲了不至於爲每一個設備製造商做適配(其實資源文件的分包就算適配了:drawable-hdpi,drawable-ldpi),將不同屏幕大小和不同dpi的設備大致劃分爲四類,如下圖:
大家可以看到T-Mobile G1的參數屬於mdpi區域的,以上就是取160dpi作爲基準的原因。

2.如果設定寬高爲釐米,或者英寸之類的物理單位,屏幕根據dpi的大小來計算要顯示多少像素才能達到這個物理單位,不是更好?爲什麼要引入dp?

如果有興趣可以看一下這個類的源碼(網址):GrepCode: android.util.DisplayMetrics (.java) ,這個類中有很詳細的dpi相關的成員函數和變量,下面的代碼是在開發時獲取dpi的代碼,
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
iDensity = (int)( metrics.density * 160 );


(1)我先回答前半部分,“如果設定寬高爲釐米,或者英寸之類的物理單位,屏幕根據dpi的大小來計算要顯示多少像素才能達到這個物理單位,不是更好?”
答:我認爲設置寬高爲釐米/英寸,然後先通過上面代碼動態計算dpi的值,然後再根據計算出的dpi計算出顯示控件需要的寬和高是可行的,但是絕對不是更好,而是非常差,因爲開發的原則遵循的是界面設計和功能邏輯分離,在程序中每次都首先需要計算一下dpi才能設定其他控件的寬高屬性是很不友好的,你想想,你啓動了某個程序,它界面一直出不來,後臺還在計算着DPI,用戶體驗也不會好,超過5s估計就被當作ANR給kill掉了。

(2)爲什麼要引入dp?
答:dp實際是dip(density independent pixel),獨立密度像素,意思就是與density密度(dpi)無關,我使用dp作爲單位設置控件,不管你什麼屏幕大小,多大的dpi,顯示的效果始終保持一致。假如我們不引入dp,還是使用原始的px,現在我們需要在手機屏幕上繪製一條直線,在160dpi(每英寸160個像素點),而寬度是1英寸的手機上做開發和測試工作,我們設置這條直線長度是160px(佔據160個像素點),也就是直線長度正好是手機的寬度,開發工作完成,我們把app發佈到市場上,這時候JJ Ying用他同樣寬度1英寸,但是240dpi的手機安裝了這個app,他能不抓狂!本該長度有屏幕這麼寬的線視覺上只有原來的2/3,如果整個UI都使用px作爲單位,就會有如下的效果。
Example application without support for different densities, as shown on low, medium, and high density screens.
上面這張圖來自Google的開發網站。如果引入dp這個單位,這種問題就不會發生了,還是以上面的例子說明,如果在160dpi的設備上使用的是160dp,無論移植到240,120dpi上顯示效果都是一致的。px和dp的換算公式px = dp * (dpi / 160),效果如下圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章