2011年8月2日 星期二

Android dpi / px / dp / 研究

最近工作上剛好遇到Android dpi 相關的問題, 紀錄一下研究筆記.
  • 基本觀念:
    • Resolution(px): 就是我們熟知的解析度, 如1024x600.
    • Size(dp/dip): 在Android上實際看到的大小, 若定義100dp, 實際在各種尺寸, dpi定義正確的裝置上, 看起來的實際大小應該要差不多.
    • Density(dpi): Dot Per Inch, 每一英寸有幾個點.
    • px = dp * (dpi / 160) Android官方公式
  • 問題: DPI設定錯誤會發生什麼事情
    • 在開發Android Platform時必須要決定dpi的數值, 錯誤的dpi會讓程式UI比例呈現異常, 如Galaxy Tab 7". (該device設定dpi為240, 表示螢幕每一英寸應該要能夠顯示240個點, 但根據DPI Calculator, 7" 1024x600每一英寸只能顯示169個點, 所以當ui resource是用dp定義width/ length的話, 經過公式換算後, 實際看到都會被放大約1.5倍)
  • 研究 : 今天如果我們有個裝置是7" 1280x800解析度, 那我們的dpi到底該定義多少?
    • 若根據DPI Calculator, 該裝置每一英寸能看到215個點, 反推螢幕上能顯示的大小
      • 寬1280 = dp * (215/160), dp約為 952dp
      • 高  800 = dp * (215/160), dp約為 595dp
    • Android Developer - Configuration Example, 直接定義了各尺寸螢幕該容納的dp大小
      • 320dp: a typical phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
      • 480dp: a tweener tablet like the Streak (480x800 mdpi).
      • 600dp: a 7” tablet (600x1024 mdpi).
      • 720dp: a 10” tablet (720x1280 mdpi, 800x1280 mdpi, etc).
    • 若為7"裝置, 所以就用600 dp來反推dpi
      • 高 800 = 600 * (dpi/160), dpi約為 213dp
    • 之所以是用寬度width反推, 而不是高度height反推是因為, 在操作畫面的時候, 垂直空間不足時, 上下滑動是很直覺的操作, 但左右移動卻比較罕見, 寬度width定義大小必須要比較注意.
      • 所以Android Developer新增了Declaring Tablet Layouts for Android 3.2, 優先考慮smallest width dp(layout-swXXXdp)
    • 因此得知7" 1280x800的顯示空間為961dp * 600dp, 須設定為213dpi
  • 個人結論
    • UI到底要用怎麼設計? 
      • 目標裝置解析度是1280x800就畫1280x800 px的圖. 
      • 在定義layout resource時, 要用dip/dp指定長寬, 而非px. (利用px = dp * (213/160)可推出dp)
      • 使用Relative Layout, 而非Absolute Layout
    • 想要支援dp較小的裝置要怎麼辦?
      • 定義不同的layout吧, 如layout-normal.
Ref:
1. http://developer.android.com/guide/practices/screens_support.html
2. http://developer.android.com/guide/topics/resources/providing-resources.html
3. http://android-developers.blogspot.com/2011/07/new-tools-for-managing-screen-sizes.html
4. DPI Caclulator

5 則留言:

  1. 謝謝您的分享,想請問如果我的目標裝置是hdpi的話(moto defy) 那我在定義layout resource時,可以直接px即dp嗎?(也就是不用換算公式。)

    回覆刪除
  2. 不行, 根據google developer hdpi是使用在螢幕161dpi~240dpi, 只有在目標裝置是剛好160dpi才可以.

    回覆刪除
  3. 謝謝你的分享, 想請教問您一個問題, 我目前有一台7吋800*480的device把dpi改成200, 為什麼字型都會出現明顯的鋸齒呢? 是因為200不是標準的dpi嗎? 若我硬要用200dpi, 這個鋸齒的現象有辦法解嗎? 謝謝!! (我是以前華碩的UE Hank, 記得我嗎?)

    回覆刪除
    回覆
    1. 我是猜,因為解析度不夠,你把DPI改大就會怪怪的。
      因為在固定解析度的狀態下,同樣空間(1CM x 1CM),能夠顯示的pixel 是固定的,不會因為你把DPI改大可以突破限制(螢幕hardware spec)。

      把DPI改200就是告訴系統這個空間能塞200個pixel進去,但因為你的螢幕就只能夠顯示160個pixel,導致有40個pixe被忽略掉,鋸齒就會產生。

      解決方式既受找到最佳dpi囉,但鋸齒無法消失,螢幕就是那麼差的解析度你是想怎樣XD

      刪除
  4. 哈 了解 感謝!! 但我調到240就沒有鋸齒了, 所以在猜是不是因為200是非標準的dpi, 因為目前在做車用, 若照google建議的值訂, 看起來非常小, 所以目前才在想用調DPI的方式讓它放大

    回覆刪除