顯示具有 androidMultipleScreens 標籤的文章。 顯示所有文章
顯示具有 androidMultipleScreens 標籤的文章。 顯示所有文章

2012年10月16日 星期二

[Android] layout qualifier

ex: In API 3.1

layout resource...
  • only in layout-w720dp -> crash
  • only in layout-xlarge -> ok (3.2 also ok)

cannot use layout-xlarge-w720dp!

2012年10月10日 星期三

[AndroidDev] Screen Compatibility Mode

Notice:
如果你所開發的 app,是小於 Android 3.0 且已經能在 tablet 上正常顯示,應該關閉此功能以維持 the best user experience。

Definition:
  • 為了幫助不能在大螢幕上正常顯示 layout 的 app 的模式。
  • 但!! Screen compatibility mode 不是作為解決顯示在 larger screen 的根本方法,因為他是放大 layout 因此使得畫面變模糊。


有以下兩種版本:

Version 1 (Android 1.6 - 3.1)
  • 系統以 normal size 來畫 layout,剩餘沒填滿的地方,則都填入黑色。
  • 僅適用於 screen size 320dp x 480dp。
  • To disable this version of screen compatibility mode, you simply need to set 
    • android:minSdkVersion or android:targetSdkVersion to "4" or higher, or
    • android:resizeable = "true".
Version 2 (Android 3.2 and greater)
  • 系統以 normal size 來畫 layout,再放大 layout 填滿 screen,所以可能會顯得模糊。
  • 如果 app 沒有宣告 <supports-screens android:largeScreens="true" />,那在 system bar 會出現選項(an icon with outward-pointing arrows)讓 user 選擇是否開啟此功能;但若 app 有宣告,user 則不能選擇。

Disabling Screen Compatibility Mode

讓 user 自行選擇是否使用(>= Android 3.2):
  • set both android:minSdkVersion and android:targetSdkVersion to "10" or lower and does not explicitly declare support for large screens using the <supports-screens> element.
  • set either android:minSdkVersion or android:tagetSdkVersion to "11" or higher and explicitly declares that it does not support large screens, using the <supports-screens> element.

Easiest:
表示支援所有大小的 screen,系統會 resize layout 每個 screen。


Easy but has other effects:
In your manifest's <uses-sdk> element, set android:targetSdkVersion to "11" or higher:

表示你的 app 支援 Android 3.0 與能正常執行於 larger screen size。

Caution:
When running on Android 3.0 and greater, this also has the effect of enabling the Holographic theme for you UI, adding the Action Bar to your activities, and removing the Options Menu button in the system bar.
If screen compatibility mode is still enabled after you change this, check your manifest's and be sure that there are no attributes set "false".


Enabling Screen Compatibility Mode

  • 如果是開發 Android 3.2 (API level 13) or higher 的 app 可以用 <supports-screens> 決定是否使用次功能。
  • 設定 android:minSdkVersion or android:targetSdkVersion to "11" or higher,user 則不能使用。(?)
If either of these are true and your application does not resize properly for larger screens, you can choose to enable screen compatibility mode in one of the following ways:

表示你 app 支援的 the maximum "smallest screen width" 是 320 dp,也就是說當 device screen 的 smallest screen width 大於 320 dp,user 就能使用 screen compatibility mode。

強制開啟此功能
If your application is functionally broken when resized for large screens and you want to force users into screen compatibility mode (rather than simply providing the option), you can use the android:largestWidthLimitDp attribute:


<supports-screens> 設為 true,表示你的 app 支援該大小的 screen,不使用此功能。


* Reference
- Screen Compatibility Mode
- Screen Compatibility Mode

2012年10月8日 星期一

Supporting Multiple Screens - 換算

算式
  • px = dp * (dpi / 160)
  • dp = px /(dpi/160)
  • dpi type = squrt(xx + yy) / inch
  • sqrt(xx + yy) / dpi type = inch

Examples:
  • not2 5.5" 1280*720 pixels
    • 267 dpi -> xhdpi
  • Amazon Kindle Fire HD 7" 16GB 7" 1280 x 800 pixels
  • Google Nexus 7 16GB 7" 1280 x 800 pixels
    • 191 dpi -> hdpi
  • ASUS Eee Pad Transformer Prime TF201 32GB 10.1" 1280 x 800 pixels
  • SAMSUNG GALAXY Note 10.1 Wi-Fi 10.1" 1280 x 800 pixels
    • 132 dp -> mdpi


dpi
  • ldpi: ~ 120 dpi
  • mdpi: 120 dpi ~ 160 dpi
  • hdpi: 160 dpi ~ 240 dpi
  • xhdpi: 240 dpi ~ 320 dpi

dp to screen size examples:
  • 480 dp
    • 480 mdpi
      • 480 px -> 4" ~ 3"
    • 720 hdpi
      • 1080 px -> 9.5" ~ 6.3"
    • 960 xhdpi
    • 1920 px -> 11.3" ~ 8.4"
  • 600 dp, about 7"
    • 600 mdpi
      • 600 px -> 7" ~ 5.3"
    • 900 hdpi
      • 1350 px -> 11.9" ~ 7.9"
    • 1920 xhdpi
      • 3840 px -> 22.6" ~ 16.9"

[AndroidDev] Supporting Multiple Screens

Android system 用以下方式使得你 App 不因螢幕密度有所改變 (density independence):
  • Scales dp units as appropriate for the current screen density
    • Use wrap_content, fill_parent, or dp units when specifying dimensions in an XML layout file
    • Do not use hard coded pixel values in your application code
    • Do not use AbsoluteLayout (it's deprecated)
  • Scales drawable resources to the appropriate size, based on the current screen density, if necessary.
    • Supply alternative bitmap drawables for different screen densities
=> Android System 依據 screen size/density 調整 layout;依據 screen density 調整 bitmap drawables。


How to Support Multiple Screens
  • Explicitly declare in the manifest which screen sizes your application supports
    • 宣告 <supports -screens="-screens"> 以避免你的 app 被從 google play 下載到不合的裝置。
    • 但當運作在較大的螢幕上時會影響 screen compatibility mode 的運作。
  • Provide different layouts for different screen sizes
    • 提供不同 layout for 不同螢幕大小,利用空間及便於 user 操作。
    • ex: small, normal, large, and xlarge。
    • 但是在 Android 3.2 (API level 13) 以上 screen size groups are deprecated,應改使用 sw-dp configuration qualifier。
  • Provide different bitmap drawables for different screen densities
    • 提供不同大小的圖片資源。
    • ex: ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)。
    • 假如只提供預設大小 (drawable, mdpi),那麼圖片在 hdpi 被放大,ldpi 縮小。

系統選擇 resources 的方式

  • The system uses the appropriate alternative resource
    • 依據螢幕 size and density 和你所提供的 resources 及所設定的 qualifier 對應出最適合的 resources,無則使用預設放大縮小(ex: drawable)。
    • 但在使用預設前,系統會先找是否能使用其他 density resources 的可能。
    • ex: 若需要 ldpi,但只有 hdpi and mdpi,那麼系統會優先選擇 hdpi 的,因為改變較小,hdpi * 0.5 < mdpi * 0.75。 
  • Eliminate resource files that contradict the device configuration. 
    • 依 qulifier 篩選,刪去不合者,但 Screen pixel density 不合時並不會刪去,Android 會選擇最適合 螢幕密度的(most closely matches the device screen density)。 
    • 有以下 qulifier: 
      • MCC and MNC 
      • Language and region 
      • smallestWidth(Added in API level 13.) 
      • Available width(Added in API level 13.) 
      • Available height(Added in API level 13.) 
      • Screen size(Added in API level 4) 
      • Screen aspect
        • long: Long screens, such as WQVGA, WVGA, FWVGA 
        • notlong: Not long screens, such as QVGA, HVGA, and VGA 
      • Screen orientation 
      • UI mode(Added in API level 8, television added in API 13) 
      • Night mode( Added in API level 8.) 
      • Screen pixel density (dpi) 
      • Touchscreen type Keyboard availability 
        • Primary text input method 
        • Navigation key availability 
        • Primary non-touch navigation method 
      • Platform Version (API level) 
Note: 
  • 選擇 size qualifiers 時,系統會選擇較小 screen size 的資源,
    • ex: large screen size 使用 normal screen size resources。 
  • 但如果只有較大 screen size resources 可用時,則會 crash
    • ex: normal screen size,但只有 large size resource。 
Tip: 
如果不想要被放大縮小,則可將圖片放入 nodpi;沒有 qualifier,是預設仍會放大縮小。


New qualifiers in Android 3.2 
  • 在 Android 3.0 時,要提供給 tablet 使用的 layout 可放入 res/layout-xlarge/,但這樣如果想在 7" 上也使用 tablet layout,則大部份都會不合條件,7" tablet 會和 5" handset 一同屬於 large group,這樣開發者變無法藉 screen size group 讓 7" tablet 能使用不同的 layout,因此在 Android 3.2 有了新的 qualifier,swdp
  • qualifiers 上指定的 size 應該為你畫面呈現時所需要的空間 (activity's window, include action bar),因為 Android System 可能會佔掉些空間 (such as the system bar at the bottom of the screen or the status bar at the top),所以系統是扣除 system UI 後的大小才是有效範圍
利用 qualifier 使用不同資源:
  • Create a new directory in your project's res/ directory and name it using the format:
    • <resources_name>-<qualifier>
      • <resources_name> is the standard resource name.
        • ex: drawable, layout, 
      • <qualifier> is a configuration qualifier.
        • ex:  hdpi, xlarge..
    • 可同時使用多個,用 dash (-) 做為分隔即可。
  • 在該指定的 directory 下放入相對應的 configuration-specific resources,resource 命名需和 default resources 相同,系統才能替代。


Scaling Bitmap objects created at runtime
  • a Bitmap object 系統視其為 mdpi,並且會使用 "auto-scaling"。
    • 若是想建立符合 screen density 的 bitmap,使用 setDensity() 指定是 DisplayMetrics#DENSITY_HIGH, DisplayMetrics#DENSITY_LOW...etc。
    • 如果是透過 BitmapFactory 建立 bitmap (ex: from a file or a stream),使用 BitmapFactory.Options 去設定屬性,做為系統是否 scale it 的參考,ex:
      • inDensity: 設定 bitmap density。
      • inScaled: 指定 bitmap 是否縮放以符合 screen size。如果設為 false,則表示關閉 pre-scaling 功能,那麼系統則會 auto-scale it at draw time。
  • auto-scale 會比 pre-scaling 花費較多 CPU 資源但較節省 memory 空間。
Note:
In Android 3.0 and above, there should be no perceivable difference between pre-scaled and auto-scaled bitmaps, due to improvements in the graphics framework.


To summarize, you should be sure that your application layout: 
  • Fits on small screens (so users can actually use your application) 
  • Is optimized for bigger screens to take advantage of the additional screen space 
  • Is optimized for both landscape and portrait orientations 



* Reference
- Supporting Multiple Screens | Android Developers
- Providing Resources | Android Developers

2012年9月26日 星期三

[AndroidDev] New resources selector (>= API 3.2)

Screen density dpi (dots per inch)
ex: 相同 physical area "low" density 會比 a "low" density screen "normal" or "high" density screen 較少 pixel。

dp (density-independent pixel)
  • The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen
  • The baseline density assumed by the system for a "medium" density screen (160 dpi).
  • px = dp * (dpi / 160)
    • ex: on a 240 dpi screen, 1 dp equals 1.5 physical pixels.
  • scaling ratio
    • 3(ldpi) : 4(mdpi) : 6(hdpi) : 8(xhpi)
    • ex: 480 x 800 hdpi/1.5 -> 320 x 533 mdpi in dp's

Screen size
  • Supported from 1.6.
  • 是系統依照 pixel and density 去算出長寬的 dp 然後對應所得。
  • Resolustion convert to dp presentaion of mdpi and decide its size (small, ..)。
  • 分類:
    • xlarge screens are at least 960dp x 720dp. (>= 2.3)
      • approximately-10” tablets, ex: Motorola Xoom
    • large screens are at least 640dp x 480dp.
      • ex: Dell Streak and original 7” Samsung Galaxy Tab
    • normal screens are at least 470dp x 320dp.
    • small screens are at least 426dp x 320dp.
      • Android does not currently support screens smaller than this.
  • 將裝置 dpi 轉至 mdpi,對應上表,長寬最接近且不小於標準之分類。ex:
    • A QVGA screen is 320x240 ldpi.
      • ldpi * 4/3 = mdpi
      • Result: 426dp x 320dp => small
    • The Xoom is a typical 10” tablet with a 1280 x 800 mdpi screen.
      • Result: 1280 x 800 => xlarge
    • The Dell Streak is a 800 x 480 mdpi screen.
      • Result: 800 x 480 => large
    • A typical 7” tablet has a 1024 x 600 mdpi screen.
      • Result: 1024 x 600 => large
      • But!! Exception "Samsung Galaxy Tab"
      • Samsung Galaxy Tab 1024 x 600 7” 應該是為 large,但因為 device configure 視為 hdpi 所以 hdpi * 2/3 = mdpi => 682dp x 400dp => normal!! 所以它應該是 large 但系統會將其視為 normal。
      • This was a mistake in the framework’s computation of the size for that device that we made. Today no devices should ship like this....

新增於 3.2 的屬性:
  • width dp
    • 現在螢幕方向的寬(dp),也就是當方向改變,寬也會隨之改變。
    • the current width available for application layout in “dp” units; changes when the screen switches orientation between landscape and portrait.
  • height dp
    • 現在螢幕方向的高(dp),也就是當方向改變,寬也會隨之改變。
    • the current height available for application layout in “dp” units; also changes when the screen switches orientation.
  • smallest width dp
    • 螢幕高與寬的最小值,此值固定,不會因為螢幕方向改變而改變。
    • the smallest width available for application layout in “dp” units; this is the smallest width dp that you will ever encounter in any rotation of the display.

Typical numbers for screen width dp are:
  • 320
    • a phone screen 
    • 240 x 320 ldpi, 320 x 480 mdpi, 480 x 800 hdpi, etc
  • 480
    • a tweener tablet like the Streak 480 x 800 mdpi
  • 600
    • a 7” tablet 
    • 600 x 1024
  • 720
    • a 10” tablet
    • 720 x 1280, 800 x 1280, etc


Resources Selector Examples

限定使用資源的最小寬度(smallest-width),如下:
res/layout/main_activity.xml           # For phones
res/layout-sw600dp/main_activity.xml   # For 7” tablets
res/layout-sw720dp/main_activity.xml   # For 10” tablets
Android 會選擇最接近但不大於的自身寬度的資源,如 700dp x 1200dp tablet 會使用 layout-sw600dp 裡的資源。


限定使用資源的寬度(width),假設你想直向時只顯示某區塊,而橫向時因為寬度較大,想顯示多點內容,可以使用這方式,如下:
res/layout/main_activity.xml          # Single-pane
res/layout-w600dp/main_activity.xml   # Multi-pane when enough width

smallest width < 600 時使用 layout; 大於 600 則會依據方向所在的寬使用 layout-sw600dp 或 layout-sw600dp-w720dp:
res/layout/main_activity.xml                 # For phones

res/layout-sw600dp/main_activity.xml         # Tablets

res/layout-sw600dp-w720dp/main_activity.xml  # Large width



// 或是寫成 layout-sw600dp-port,表示直向時使用此

res/layout/main_activity.xml                 # For phones

res/layout-sw600dp/main_activity.xml         # Tablets

res/layout-sw600dp-port/main_activity.xml    # Tablets when portrait


和舊的 qualifier 一同使用,如下:
// 使用 layout-swNNNdp 比 layout-port 好
res/layout/main_activity.xml                 # For phones
res/layout-land/main_activity.xml            # For phones when landscape
res/layout-sw600dp/main_activity.xml         # Tablets


相容性寫法

Type 1 - Using new qualifiers with old qualifiers
new qualifiers(ex: layout-sw600dp) 會被舊版本忽略,所以以下寫法能 work:
res/layout/main_activity.xml           # For phones
res/layout-xlarge/main_activity.xml    # For pre-3.2 tablets
res/layout-sw600dp/main_activity.xml   # For 3.2 and up tablets

Type 2 - Using new qualifiers with old qualifiers for different layouts
利用 values selector 使用相同名稱指向不同 layout:

res/layout/main_activity.xml           # For phones
res/layout/main_activity_tablet.xml    # For tablets


res/values-xlarge/layout.xml
res/values-sw600dp/layout.xml

res/values-sw600dp/layout.xml:

    
            @layout/main_activity_tablet
    


Type 3 - Select in code
在程式中判斷螢幕大小決定 layout:
public class MyActivity extends Activity {
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate();

        Configuration config = getResources().getConfiguration();
        // config.smallestScreenWidthDp: >= API 3.2
        if (config.smallestScreenWidthDp >= 600) {
            setContentView(R.layout.main_activity_tablet);
        } else {
            setContentView(R.layout.main_activity);
        }
    }
}


* Reference
- Android Developers Blog: New Tools For Managing Screen Sizes
- Supporting Multiple Screens

2012年5月2日 星期三

[UI] Supports Multiple Screen - Scaling

If layout is dependency on pixel...
  • 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不同的适配问题分析 **

2012年4月28日 星期六

[UI] Supporting Multiple Screens - Terms and Concepts

* Terms and Concepts
  • Screen size (inch)
    • 以螢幕對角線為準,可分為small, normal, large, and extra large。
  • Aspect ratio
    • 螢幕的長寬比。
  • Resolution 解析度
    • The total number of physical pixels on a screen.
  • Density
    • pixel 密度 (the spread of pixels across the physical width and height of the screen)。
    • 可分為 low, medium, large, and extra large。
  • Density-independent pixel (dp)
    • A virtual pixel unit that applications can use in defining their UI, to express layout dimensions or position in a density-independent way。
    • pixels = dps * (density / 160)。
  • px (pixels)
    • 像素,對電腦而言,所有人眼所見的影像都是螢幕上一連串的光點的構成的,這些光點是電腦顯示的最小單位。
    • 光點的數量越多,影像提供的細節就越多。

* Range of screens supported
At run time, the platform handles the loading of the correct size or density resources, based on the generalized size or density of the current device screen, and adapts them to the actual pixel map of the screen.
  • Sizes
    • small, normal, large, and xlarge
  • Densities
    • ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)
    • The xhdpi density category was added in Android 2.2 (API Level 8). 
    • The xlarge size category was added in Android 2.3 (API Level 9).

* Android support application to display resources
  • Pre-scaling of resources (such as image assets)
  • Auto-scaling of pixel dimensions and coordinates
  • Compatibility-mode display on larger screen-sizes

* 若要指定特定長度或大小,要使用以下單位,才不會因為系統的 resolution 不同而呈現不同結果:
  • sp (scaled pixels): 用於字體。
  • dip/dp (density independent pixels): 系統會依比例呈現,使得結果不受 pixel 影響。


* Reference
- Supporting Multiple Screens
- long or notlong
- 關於android系統資源更換-語言切換或配置改變
- 屏幕分辨率
- 关于android多分辨率中的density和density-independent pixel的区别
- 何謂解析度、DPI?
- android平台下单位px,dip,sp的区别