- mdpi -> ldpi: 圖會變大而失真
- mdpi -> hdpi: 圖會變小 (因為 pixel 變多/ inch)
- 也因此在 ldpi mdpi hdpi 上會顯得大小不一
但若是採用 independency methods...
- 則系統會選擇不同的 resource 所以如果只有 mdpi:
- 則會縮小顯示在 ldpi device 上
- 則會放大顯示在 hdpi device 上 而可能失真
- 最終在 ldpi mdpi hdpi 大小會相同
Multiple screens support
- Started in Android 1.1
- Resources management added in 1.5
- Compatibility mode added in 1.6
Inside Android
- Everything is pixels
- Resolution independent units
- dip and dp
- pt and sp
- mm, in
- Layouts
Resources management
- Pre-scaling
- Auto-scaling
- By default, resources are mdpi
- res/drawable
- Use dpi-specific resources
- res/drawable-hdpi
- res/drawable-ldpi
- res/drawable-mdpi
Pre-scaling (android:anydensity="true")
- 系統善用 resources 的方式。系統會根據裝置 density 去選擇要使用那種大小的圖片(res/drawable-ldpi, drawable-mdpi, drawable-hdpi...)或者是放大/縮小 default drawable 來符合當下螢幕密度。
- 如果 application 中沒有相符合的 resources 那麼系統就會使用預設的(res/drawable or res/drawablw-mdpi)並且放大或縮小它來顯示。
- res/drawable 被視為 baseline screen density (mdpi)。
- 如果取得已被放大/縮小的圖片的 dimension,那麼值會是已經放大/縮小後的。
- Examples:
- for an hdpi device, when there is only mdpi image 100 x 100, then the image will be pre-scaled to 150 x 150;
- for an mdpi device, when there is only hdpi image 150 x 150, then the image will be pre-scaled to 100 x 100;
- 此功能預設是 true,如果不想讓圖片被經過這樣的處理或是放大/縮小後顯示,可...
- 將 resources 放在 res/drawable-nodpi 下。
- 在 AndroidManifest 中設 <supports-screens android:anydensity="false">。
- 設定 Bitmap 的 isScaled() 為 false。
- 當 pre-scaling 被關閉,系統便會在畫圖時縮放圖片(see Auto-scaling),但不建議關閉 pre-scaling。
Auto-Scaling
- 若想強迫使用 auto-scaling,則是要關閉 pre-scaling,ex: 在 AndroidManifest 中設 <supports-screens android:anydensity="false">。
- 為了確保在不同裝置上能顯示相同的大小,所以即使 pre-scaling is disable 仍會再畫圖時做 auto-scaling。
- CPU expensive, but use less memory.
- Bitmap created at runtime will auto-scaled.
AndroidManifest.xml
- android:anyDensity: 程序是否可在任何密度的螢幕上執行。主要是為使用了 px 作為單位的圖片。
- If false: 系統就會 pre-scaling resources/density-compability,根據不同的屏幕密度將 px 值轉換為合理的大小。
- If true: 就會關閉 pre-scaling resources/density-compability 。
- 如果程序是以 dp 作為長度單位的,則不會受此值影響。
- android:xxxScreens: 是否支持某屏幕(physical size)。
- If false: 表示不支援該大小的螢幕,系統會啟用 size-compability 特性,即只顯示標準屏幕(normal size, mdpi)的大小。
- ex: 即使是 hdpi 仍以 mdpi 的大小顯示,其餘部份則會留黑。
- If true: 表示支援該大小的螢幕,系統就不會做任何處理直接顯示。
可以利用下列兩種方式來在程式中相對的長度:
計算出 dipValue 在該螢幕中應該為的 pixel value。
// Convert the dips to pixels final float scale = getContext().getResources().getDisplayMetrics ().density; pixels = ( int) (dipValue * scale + 0.5f );宣告 dip 在 resources values 中,再取出該 pixel size by getDimensionPixelSize()。
20dip
Resources r = aContext.getResources(); int length = r.getDimensionPixelSize(R.dimen.length);
* Reference
- 2009_Android_resolution_independence_and_high_performance_graphics_RomainGuy ***
- Supporting Multiple Screens
- Situee's Blog - iPhone,Technology: Pre-scaling, Auto-Scaling and Screen Density
- How to Support Multiple Screens in Android without the need to Provide different bitmap drawables for different screen densities
- Android Samsung S I9000 screen size and density issues
- Android 屏幕兼容性
- Android ApiDemos示例解析(63):Graphics->Density (上) ***
- Android ApiDemos示例解析(63):Graphics->Density (下) ***
- android应用 DPI不同的适配问题分析 **
沒有留言:
張貼留言