android適配之dp,px深度解析

     在android開發中關於佈局文件中組件的大小官方建議使用dp,不建議使用px,那麼問題來了,Why?
首先我們要知道
   px = dp * (dpi / 160)(這裏的dp和dip都表示設備獨立像素,以下相同)
   px: pixels(像素)。設備的真實像素。顯示效果和屏幕密度有關,和屏幕尺寸無關。相同像素,像素密度越大,顯示的效果越小。
   dpi: dots per inch (屏幕像素密度)。每英寸上的像素數。
   dip: device independent pixels(設備獨立像素)。不同設備有不同的顯示效果,這個和設備硬件有關,不管屏幕密度怎樣變化,只要屏幕的物理尺寸不變,實際顯示的尺寸就不會變化。
     所以,由於國內手機市場出現各種尺寸、各種像素密度的android手機,因爲WVGA的分辨率達到了800*480像素,HVGA的分辨率是480*320像素,QVGA的分辨率是240*320,但是它們的屏幕尺寸基本相同,一般我們爲了支持WVGA、HVGA和QVGA、爲了解決屏幕尺寸相同而像素密度不同的情況,我們建議使用dp,而不建議使用px,因爲它不依賴於像素。

下面這篇文章可以做深入理解之參考,[url=http://blog.csdn.net/eggcalm/article/details/7006378]查看原文[/url]: 
   今天偶然間問了同事一個關於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)這四種),而是使用設備真實的像 素密度,那麼得出的像素數目雖然各不一樣,但是最終顯示出來的物理尺寸確實一樣大的,而這種計算方法,我認爲是忠於像素密度無關的理論的。 

  


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