Android裏神奇的dp

原文:http://blog.csdn.net/eggcalm/article/details/7006378


今天偶然間問了同事一個關於dp單位的問題,然後由這個問題引發的一連串的問題徹底顛覆了我關於dp的理論體系。



我那個問題是這樣的:既然dp的本質是物理尺寸,爲什麼不用cm或者mm等傳統長度單位替代?


然後他回答我dp是和像素密度無關的。。。我對這個回答不屑一顧,不過他接下來的一句話把我徹底震驚了,那句話是這樣的:在你的手機上320dp就剛好滿屏了,310dp就差一點點滿屏。


我的手機是HTC Desire,這個理論我聞所未聞,然後馬上做了個小實驗,事實確實是這樣,把一個TextView背景設成紅色,寬度設成320dp,能看到滿屏,310dp就差那麼一點點。


看到這個測試結果的時候,我再一次崩潰了,我希望同事第二句話是一個美麗的錯誤,我無法接受這麼久以來我理解的東西是錯誤的,可是事實是殘酷的。


Android Developers關於dp的文檔我看過N次,那個px和dp的轉換公式我記得很清楚: px = dp * (dpi / 160),可是今天翻了源碼了才發現,原來這裏的dpi是歸一化後的dpi,可能值只有120(low)、160(medium)、240(high)、320(xhigh)四種,而我之前理解的竟然是實際設備真實的dpi!


G7的真實dpi是252,根據我以前的理解,310dp換算成px應該是:310 * (252 / 160) = 488像素,而G7水平方向是480px,310dp在這上面絕對滿屏都不止了,事實上Android系統並沒有拿252作爲dpi來計算,而是將G7視作hdpi設備,然後使用240dpi來計算最終像素,所以在G7上320dp剛好是:320 * (240 / 160) = 480像素,剛好滿屏了,310dp確實要差一點點。


搞清楚這個問題後,我心裏稍微好受點了,可是另一個問題接踵而來:
dp的本質還是物理尺寸,難道不是嗎?儘管Android系統對待dp這事上,將所有設備視爲四種:120(low)、160(medium)、240(high)、320(xhigh),在160dpi上,160dp就是1英寸,在240dpi上,160dp還是1英寸,120dpi和320dpi也還是1英寸,雖然他們佔用的像素數不一樣,但是最終顯示出來的效果都是佔用了屏幕上1英寸的範圍。這套體系其實是非常合理的,一個寬爲160dp的按鈕,它在所有設備上佔用的物理尺寸應該是一樣大才合理,這樣他們對人眼所形成的張角才一樣大,觀看或者閱讀的感覺才一致(姑且不考慮按鈕的背景是否一樣細緻)。這應該是Android系統引入dp概念的原因,因爲手機屏幕的像素密度相差實在太大了,web那套東西已經完全不適用,你想電腦屏幕的像素密度能相差多大?


終極問題來了,現實生活中真的只有以上四種不同像素密度的設備嗎?不可能。雖然所有這些設備都可以粗略地劃分爲low、medium、high、xhigh四種密度,可是對於劃在同一範圍內但具有不同像素密度的兩個設備來說,同樣的dp最終所佔用的物理尺寸是不一樣的。舉個例子,G7(HTC Desire)的屏幕尺寸是3.7英寸,分辨率是480*800,像素密度是252dpi,G10(HTC Desire HD)的屏幕尺寸是4.3英寸,分辨率同爲480*800,像素密度是217dpi。假設現在有一個按鈕,它的寬度設爲100dp,由於G7和G10同被劃分爲hdpi,那麼在這兩個設備上,這個按鈕的實際寬度是:100 * (240 / 160) = 150像素,可由於這兩個設備的實際像素密度是不一樣的,所以真實的顯示效果是:這個按鈕在兩個設備上的實際物理尺寸是不一樣大的。而這,和Android進入dp的概念是相悖的。


你可以說對於同屬於hdpi的設備而言,這個差別很小,但是在ldpi和hdpi之間這個差別就很明顯了。我非常認同,可是如果在將dp轉化爲px的時候,不是使用歸一化dpi(也就是120(low)、160(medium)、240(high)、320(xhigh)這四種),而是使用設備真實的像素密度,那麼得出的像素數目雖然各不一樣,但是最終顯示出來的物理尺寸確實一樣大的,而這種計算方法,我認爲是忠於像素密度無關的理論的。


最後我還是想說,如果Android希望一個寬度爲160dp的按鈕在任何設備上都是1英寸大,那爲什麼不直接使用英寸作爲度量單位呢?


如果你有好的想法,歡迎留言。



UPDATE:

今天下午在回答factar網友的問題的時候,我上面那個“終極問題”終於找到了一個合理的答案。在factar貼的網址裏,我發現一句重要的話:

However, bitmap scaling can result in blurry or pixelated bitmaps, which you might notice in the above screenshots.

這句話的意思是說,圖片資源在縮放的時候會造成圖像模糊。按照我以上的分析,如果爲了保證相同的圖片資源在不同像素密度的設備上保持完全一樣的尺寸大小(這完全可以做到,在dp轉化成px的時候使用設備的物理像素密度參數),那圖片在不同設備上的縮放因子必然不一樣,而這會導致圖像模糊!所以我猜想Google爲了保證了圖像不會模糊退了一步,讓相同dp在不同設備上“差不多一樣大”。


還有,這個答案也糾正了我的一個誤區,現在有很多應用程序開發商爲了降低安裝包的大小,只使用一套hdpi資源或者一套xhdpi資源,而不提供mdpi資源或ldpi資源,希望在mdpi和ldpi設備上有系統完成縮放適應,雖然可行,但是我們不應忽視因爲縮放帶來的圖像模糊、顯示效果不佳的現象。

發佈了11 篇原創文章 · 獲贊 9 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章