屏幕適配html
Android運行在提供不一樣屏幕尺寸和密度的多種設備上。 對應用程序而言,Android系統提供一致的跨設備的開發環境而且處理適配不一樣顯示屏幕的大部分工做。同時,系統提供API,容許針對不一樣的屏幕尺寸和密度來控制的應用程序UI,從而爲不一樣的屏幕配置來優化UI設計。android
儘管系統會進行縮放和調整,以使應用程序在不一樣的屏幕上運行,仍然應該儘可能爲不一樣的屏幕尺寸和密度來優化應用。最大限度的爲全部設備優化用戶體驗,這樣用戶纔會認爲應用程序是真正的爲他們的設備設計的,而不是簡單的拉伸或縮放來適應他們的設備。express
按照本文檔中所述的作法,能夠建立一個應用程序,使之在全部支持的屏幕配置上正確顯示,並使用單一的.apk文件提供優化的用戶體驗。api
注:本文檔中的信息假設應用程序是爲Android 1.6(API等級4)或更高版本設計。若是要應用程序支持Android 1.5或更低,請首先閱讀 Strategies for Android 1.5.
同時,要注意的Android 3.2推出新的API,更精確地控制應用程序使用不一樣屏幕尺寸的佈局資源。若是你正在開發爲平板優化的應用程序,這些新功能尤爲重要。有關詳情,請參閱 爲Android 3.2設計平板佈局架構
屏幕支持概述app
本節概述Android對多個屏幕的支持,其中包括:在本文中和API中會用到的術語和概念的介紹,系統支持的屏幕配置的總括,以及API和底層屏幕適配特性的概覽。框架
術語和概念less
屏幕尺寸ide
實際的物理尺寸,以屏幕的對角線爲準。佈局
爲簡單起見,將全部的實際尺寸分爲四個廣義的尺寸:small(小), normal(正常), large(大), extra large(特大)。
屏幕密度
屏幕的物理面積內的像素數量,一般指的DPI(每英寸點數)。例如,「低」的密度屏幕比「正常」或「高」密度屏幕在一個給定的物理面積內具備較少的像素。
爲簡單起見,將全部的實際密度分爲四個廣義的密度: low(低), medium(中等), high(高), extra high(超高)。
方向
從用戶的角度來看,屏幕的方向。是橫向或縱向,也就是說,屏幕的比例是高或者寬。須要注意的是,不只要在不一樣的屏幕方向作不一樣的操做,還要考慮到用戶在運行時經過轉動設備切換屏幕方向的狀況。
分辨率
在屏幕上的物理像素總數。在支持多個屏幕時,應用程序不直接與分辨率相關;應用程序應該只與屏幕大小和密度相關。
密度無關的像素(DP)
在定義UI佈局時應該使用的虛擬像素單元,它用一種密度無關的方式來表達佈局尺寸或位置。
在160 dpi的屏幕上的一個物理像素,是「中等」的密度屏幕系統所承擔的基準密度。系統在運行時透明地處理任何DP單位,必要時根據實際使用的屏幕密度縮放。 DP單位轉換爲屏幕像素是簡單的:PX = DP *(DPI / 160)。例如,在240 dpi屏幕,1 DP等於1.5物理像素。定義應用程序的用戶界面時,應該老是使用DP單位,以確保不一樣密度的屏幕上正確顯示UI。
屏幕支持範圍
從Android 1.6(API Level 4)開始,Android提供了對多個屏幕尺寸和密度的支持,以反映出設備可能有的不一樣的屏幕配置。可使用Android系統的功能,爲每一個屏幕配置優化應用程序的用戶界面,從而確保應用程序爲每一個屏幕提供正常而且儘量最佳的用戶體驗。
爲了簡化爲多種屏幕設計用戶界面,Android劃分了實際的屏幕尺寸和密度範圍:
廣義的尺寸大小集合: small(小), normal(正常), large(大), and xlarge(超大)
注:從Android 3.2(API Level 13)開始,這種尺寸集合被廢棄,取而代之的是一種基於可用屏幕寬度來管理屏幕尺寸的新技術。因此針對Android 3.2以及以上版本的開發,能夠參考 爲Android 3.2設計平板佈局來獲取更多信息。
廣義的密度集合: ldpi (低), mdpi (中), hdpi (高), and xhdpi (超高)
廣義的大小和密度都圍繞一個基準配置,即正常的大小和MDPI(中)密度。這個基準配置即第一款Android設備的配置,此設備即擁有一個HVGA屏幕的T-Mobile G1(直到Android 1.6,這是Android支持的惟一的屏幕配置)。
每一個廣義的大小和密度跨越了一系列實際的屏幕尺寸和密度。例如,兩個設備,這兩個設備報告的正常屏幕尺寸和寬高比可能與手工測量時略有不一樣。一樣,兩個設備報告的hdpi的屏幕密度可能與真正的像素密度略有不一樣。 Android抽象了應用程序的這些差別,所以能夠提供廣義的大小和密度設計的用戶界面,讓系統須要處理任何最終的調整。圖1顯示了不一樣的大小和密度大體分類成不一樣的大小和密度組。
圖1. 解釋了Android對實際的尺寸和密度到廣義的尺寸和密度(數字是不許確的)的大體映射。
每個UI設計須要一個最小的空間,每個上文提到的廣義的屏幕大小都擁有一個由系統定義的最小分辨率。這些空間是以「dp」爲單位的,當定義佈局時,也應當使用相同的單位,它使系統避免了對屏幕密度變化的顧慮。
xlarge 屏幕至少 960dp x 720dp
large 屏幕至少 640dp x 480dp
normal 屏幕至少 470dp x 320dp
small 屏幕至少 426dp x 320dp
爲不一樣屏幕尺寸和密度優化應用程序的用戶界面,能夠提供任何廣義的大小和密度的alternative resources(選擇性資源)。一般狀況下,應該爲不一樣的屏幕尺寸提供alternative layouts而且爲不一樣的屏幕密度提供alternative bitmap images。在運行時,系統基於當前設備的廣義屏幕尺寸或密度爲應用程序採用適當的資源,
不須要爲每個屏幕大小和密度的組合提供選擇性資源。系統提供了強大的兼容特性,能夠處理在任何設備的屏幕上呈現應用程序的大部分工做,開發者只要實現UI技術,容許它正常調整。
注: 定義廣義屏設備的大小和密度的特色是相互獨立的。例如,WVGA的高密度的屏幕被認爲是一個正常大小的屏幕,由於它的物理尺寸是相同的T-Mobile G1(Android的設備和基線的屏幕配置)。另外一方面,WVGA的屏幕中密度被認爲是一個大尺寸屏幕。雖然它提供了相同的分辨率(像素數相同),WVGA的屏幕中密度較低的屏幕密度,這意味着每一個像素的物理面積較大,所以,整個屏幕是比基準(正常大小)的屏幕更大。
密度的獨立性
當應用程序在具備不一樣密度的屏幕上顯示時,它保留了用戶界面元素(從用戶的角度來看)的物理尺寸,即實現了「密度獨立」。
保持密度的獨立性是很是重要的,由於,沒有它,一個UI元素(如按鈕),在低密度屏幕上顯示較大而在高密度屏幕上顯示較小。這樣的密度相關的大小的變化可能會致使應用程序的佈局和可用性問題。圖2和圖3顯示了一個應用程序不提供密度獨立性時的差別。
圖 2. 應用程序不支持密度獨立,在低,中,高密度屏幕上顯示。
圖 3. 應用程序支持密度獨立,在低,中,高密度屏幕上顯示,支持良好
Android系統能夠經過兩種方式使應用程序實現密度獨立:
系統縮放dp單位以適應當前屏幕密度
系統基於當前屏幕密度按須要縮放可曳資源到合適尺寸
在圖2中,text view和bitmap以像素爲單位指定尺寸(像素單位),因此視圖的物理尺寸在地密度屏幕上要大一些而在高密度屏幕上要小一些。這是由於實際的屏幕尺寸雖然多是相同的,具備高密度的屏幕每英寸的像素越多(相同數量的像素適合在一個較小的區域)。
在圖3中,經過密度無關的像素(DP單位)指定佈局尺寸。由於密度無關的像素的基線是一箇中等密度的屏幕,一箇中密度屏幕的設備看起來和圖2中是同樣的。然而,對低密度和高密度的屏幕,系統按比例調高或調低密度無關的像素值,分別以適應屏幕。
在大多數狀況下,能夠簡單的經過用密度無關像素(dp units)來定義全部的佈局尺寸或者適當的經過"wrap_content"來確保應用程序密度無關。而後系統依據當前屏幕密度的比例因子按比例決定bitmap drawable以顯示合適的尺寸。
然而,位圖縮放可能會致使模糊或像素化的位圖。爲了不這些人爲效果,應該爲不一樣密度提供選擇性位圖資源。例如,應該爲高密度的屏幕提供更高分辨率的位圖從而系統能夠沒必要去調整爲低密度屏幕準備的位圖。如下部分描述如何爲不一樣的屏幕配置提供選擇性資源。
如何支持多屏幕
Android能夠爲當前的屏幕配置經過適當的方式管理應用程序的layout和bitmap drawables的表現,這種能力是Android支持多屏幕的基礎。系統處理的應用程序屏幕適配的大部分工做,儘管如此,爲了更妥善處理不一樣的屏幕配置,應該注意如下幾點:
在清單文件中明確聲明應用程序支持的全部屏幕尺寸
經過聲明應用程序支持的屏幕尺寸,能夠保證只有那些屏幕尺寸被應用程序支持的設備才能夠下載該應用程序。聲明對不一樣屏幕尺寸的支持,也能夠影響系統如何在更大的屏幕展示應用程序—特別地,應用程序是否在屏幕兼容模式運行。聲明應用程序支持的屏幕尺寸,應該在manifest文件中包括 <supports-screens>元素。
爲不一樣的屏幕尺寸提供不一樣的佈局
默認狀況下,Android從新調整應用程序的佈局,以適應當前的設備屏幕。在大多數狀況下,這工做得很好。在其餘狀況下,用戶界面可能看起來不太好,可能須要爲不一樣屏幕尺寸的做調整。例如,在大屏幕上,可能要調整某些元素的位置和大小,充分利用額外的屏幕空間,或在一個較小的屏幕上,可能須要調整大小,讓全部元素均可以在屏幕上顯示。可使用限定符來提供尺寸相關的資源,這些限定符包括small, normal, large, 和 xlarge。例如,一個超大大屏幕的佈局,應該在layout-xlarge/。
從Android 3.2(API Level 13)開始,上述尺寸組已被棄用,應該使用sw<N>dp 限定符定義佈局資源所需的最小可用寬度。例如,若是多窗格平板佈局至少須要600dp屏幕的寬度,應該放置在layout-sw600dp/下。使用新技術來聲明佈局資源在 爲Android 3.2設計平板佈局部分有進一步討論。
爲不一樣的屏幕尺寸提供不一樣的bitmap drawable
默認狀況下,Android縮放bitmap drawables(.png, .jpg,和.gif文件)和Nine-Patch drawables(.9.png 文件),使它們在每臺設備上呈現合適的物理尺寸。
例如,若是應用程序只爲基準,中型屏幕密度(MDPI)屏幕提供了bitmap drawable,那麼系統將會在高密度屏幕上放大它們,而在低密度屏幕上縮小它們。這種縮放可能會讓位圖產生失真。
爲了讓位圖最好的展現,應該爲不一樣屏幕密度提供不一樣分辨率的位圖。
可使用限定符來提供密度相關的資源,這些限定符包括ldpi (low), mdpi (medium), hdpi (high), 和 xhdpi (extra high)。例如,爲高密度屏幕提供的位圖應該放在drawable-hdpi/下。
與廣義的尺寸和密度相對應的尺寸和密度限定符在上文的屏幕支持範圍中有描述。
注: 若是不熟悉配置限定符和系統如何使用它們來請求選擇性資源,閱讀Providing Alternative Resources獲取更多信息。
在運行時,系統爲任何給定資源經過如下步驟來儘量確保它們在當前屏幕的顯示:
系統使用適當的可選資源
當前屏幕的大小和密度的基礎上,系統使用應用程序提供的任意尺寸和密度相關資源。例如,設備有一個高密度的屏幕而且應用程序請求一個drawable 資源,系統會尋找一個最匹配設備配置的drawable 資源目錄。與其它可選資源相比,以hdpi 爲限定符的資源目錄(好比drawable-hdpi/)會最佳匹配,因此係統使用該目錄下的drawable資源。
若是沒有匹配的資源是可用的,系統將使用默認的資源而且對其進行縮放來適應當前的屏幕尺寸和密度。
「默認」的資源是那些沒有配置限定符的資源。例如,在drawable/ 下的就是是默認的資源。系統假定默認資源是爲基線屏幕尺寸和密度而設計的。正由於如此,系統對其採起縮放是比較可取的。
然而,當系統試圖尋找一個密度相關的資源可是在密度相關的目錄下沒有找到時,系統並不老是使用默認資源。系統可能會改用其餘密度相關的資源之一,以提供更好的縮放結果。 例如,當尋找一個低密度資源而沒找到時,系統傾向於縮小高密度資源,由於系統能夠經過縮放因子0.5輕鬆地將高密度資源縮小爲低密度,這種縮放要比經過縮放因子0.75將中密度資源縮小爲低密度不易失真。
更多信息請參閱How Android Finds the Best-matching Resource。
使用配置限定符
Android支持多種配置限定符,來控制系統如何根據當前設備屏幕的特色選擇可選的資源。配置限定符是一個字符串,能夠在Android項目追加到資源目錄,並指定配置資源的內部設計。
使用配置的限定符:
在工程的res/目錄下建立一個新的目錄,並將其以以下格式命名:<resources_name>-<qualifier>
<resources_name> 是標準的資源名 (好比drawable 或者 layout).
<qualifier> 是一個配置限定符, 以下面的表1所示, 它限定了這些資源能夠用於的屏幕配置(好比 hdpi 或者 xlarge).
能夠一次使用多個 <qualifier> —使用破折號將多個限定符分開。
在這個新目錄保存適當的配置相關資源。資源文件命名務必與默認的資源文件命名一致。
好比, xlarge 是一個超大屏幕的限定符。當追加此字符串到一個資源目錄名(好比layout-xlarge),這就告訴系統這些資源是要用在擁有超大屏幕的設備上的。
表 1. 爲不一樣屏幕配置提供具體資源的配置限定符
Screen characteristic |
Qualifier |
Description |
|
Size |
small |
Resources for small size screens. |
|
normal |
Resources for normal size screens. (This is the baseline size.) |
||
large |
Resources for large size screens. |
||
xlarge |
Resources for extra large size screens. |
||
Density |
ldpi |
Resources for low-density (ldpi) screens (~120dpi). |
|
mdpi |
Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.) |
||
hdpi |
Resources for high-density (hdpi) screens (~240dpi). |
||
xhdpi |
Resources for extra high-density (xhdpi) screens (~320dpi). |
||
nodpi |
Resources for all densities. These are density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density. |
||
tvdpi |
Resources for screens somewhere between mdpi and hdpi; approximately 213dpi. This is not considered a "primary" density group. It is mostly intended for televisions and most apps shouldn't need it—providing mdpi and hdpi resources is sufficient for most apps and the system will scale them as appropriate. If you find it necessary to provide tvdpi resources, you should size them at a factor of 1.33*mdpi. For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi. |
||
Orientation |
land |
Resources for screens in the landscape orientation (wide aspect ratio). |
|
port |
Resources for screens in the portrait orientation (tall aspect ratio). |
||
Aspect ratio |
long |
Resources for screens that have a significantly taller or wider aspect ratio (when in portrait or landscape orientation, respectively) than the baseline screen configuration. |
|
notlong |
Resources for use screens that have an aspect ratio that is similar to the baseline screen configuration. |
注:對於Android 3.2以及以上版本,請參閱 爲Android 3.2設計平板佈局獲取關於新的配置限定符的更多信息(不要使用表1中的尺寸限定符)
欲瞭解更多有關如何將這些限定符與實際的屏幕尺寸和密度相對應的信息,請看本文檔前面的屏幕支持範圍
例如,下面是一個應用程序的資源列表,它爲不一樣的屏幕尺寸提供不一樣的佈局,而且爲中,高,超高密度的屏幕提供不一樣的bitmap drawable。
res/layout/my_layout.xml // layout for normal screen size ("default")
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-xlarge/my_layout.xml // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation
res/drawable-mdpi/my_icon.png // bitmap for medium density
res/drawable-hdpi/my_icon.png // bitmap for high density
res/drawable-xhdpi/my_icon.png // bitmap for extra high density
欲瞭解更多有關如何使用選擇性資源和配置限定符的完整列表(不僅是屏幕配置)的信息,請參閱Providing Alternative Resources。
注意,Android系統在運行時選擇使用哪些資源時,它使用某些邏輯來決定「最佳匹配」的資源。也就是說,使用的限定符沒有必要徹底匹配當前的屏幕配置。具體來講,當基於尺寸限定符來選擇資源時,若是沒有更好的匹配,系統會選擇使用爲比當前屏幕小的屏幕設計的資源(例如,一個大屏若是須要,可能會使用正常屏的資源)。可是,若是隻有比當前屏幕尺寸大的資源,那麼系統將不會使用這些大的資源,應用程序將會因無從選擇而崩潰。(例如,若是全部的資源都是xlarge 限定符的,可是設備是一個normal-size的設備)。
更多關於系統如何選擇資源的信息,請參閱 How Android Finds the Best-matching Resource。
提示:若是有一些繪製資源,不想讓系統進行縮放(也許是由於想要在程序運行時進行手動調整),應該將其放置nodpi 配置限定符的目錄下。這個限定符的資源被視爲密度無關,系統將不能擴展。
設計選擇性的佈局和圖片
替代資源的類型,取決於應用程序的需求。一般,應該使用尺寸和方向限定符提供選擇性的佈局資源,使用密度限定符提供選擇性的圖片資源。如下部分分別歸納了該如何使用尺寸和密度限定符提供選擇性的佈局和圖片。
選擇性的佈局
應該確保應用程序的佈局:
適合在小屏幕上(確保能夠實際使用)
在大屏幕上,確保充分利用額外的屏幕空間
適應豎屏和橫屏
若是用戶界面,須要讓位圖來適應視圖的大小(如一個按鈕的背景圖片),應該使用Nine-Patch 位圖文件。Nine-Patch文件基本上是一個PNG文件它能夠在特定的二維地區伸展。當系統須要拉伸位圖所在的視圖時,系統會拉伸Nine-Patch文件,可是僅僅拉伸的是指定區域。正由於如此,不須要提供不一樣的屏幕尺寸不一樣的圖片,由於Nine-Patch的位圖,能夠調整到任何尺寸。然而,應該爲不一樣的屏幕密提供不一樣的Nine-Patch文件。
選擇性的圖片
Figure 4. 支持各密度的位圖的相對大小
幾乎每一個應用程序都應當爲不一樣的屏幕密度提供圖片資源,由於幾乎每個應用程序都擁有一個啓動圖標,而改圖標應當在不一樣密度的屏幕上顯示良好。
注: 只需提供密度相關的位圖文件(.png, .jpg, 或者 .gif) 和 Nine-Path 文件(.9.png)。若是須要使用XML來定義形狀,顏色或者可繪製的資源,應當在默認的drawable 目錄備份一份。
要建立不一樣密度的選擇性的圖片,應該在四個廣義密度之間遵循3:4:6:8的縮放比例。好比,一箇中密度下爲48x48像素的位圖(應用程序啓動圖標),與之對應的全部不一樣的尺寸應當是:
低密度爲36x36
中密度爲48x48
高密度爲72x72
超高密度爲96x96
更多關於設計圖標的信息,請參閱 Icon Design Guidelines,它涵蓋了各類位圖的尺寸信息,好比啓動圖標,菜單圖標,狀態欄圖標,tab 圖標等等。
爲Android 3.2設計平板佈局
對於第一代運行Android 3.0的平板電腦來講,聲明平板佈局的適合方式是使用xlarge 限定符(好比res/layout-xlarge/)。爲了適應其餘類型的平板電腦和屏幕尺寸,Android 3.2引入了一種新的爲分散屏幕尺寸定義資源的方式。這種新技術是基於佈局所需的空間數量(好比600dp寬),而不是試圖讓佈局去符合廣義的尺寸分類(好比大或者超大)。
使用新的尺寸限定符
見表2,這些新的限定符,比傳統的屏幕尺寸分類(小,中,大,和超大)能提供更多的對於定義應用程序支持的屏幕的控制。
注: 使用這些限定符指定的大小不是實際的屏幕尺寸。相反,是能夠用於活動窗口的寬度或者高度尺寸,是以dp爲單位的。系統會爲系統UI使用一些屏幕空間(好比系統欄或者狀態欄),因此一些屏幕空間對應用程序是不可用的。所以,聲明的尺寸應當明確的是activity所需的尺寸—當系統聲明應當提供多少空間給佈局時,它會計算任何被系統UI佔據的空間。 同時注意, Action Bar被認爲是應用程序的一部分空間,儘管佈局沒有聲明它,所以它減小了可用的佈局空間,你必須考慮在設計以內。
Table 2. 屏幕尺寸的新的配置限定符(在Android 3.2中引入)
Screen configuration |
Qualifier values |
Description |
smallestWidth |
sw<N>dp |
The fundamental size of a screen, as indicated by the shortest dimension of the available screen area. Specifically, the device's smallestWidth is the shortest of the screen's available height and width (you may also think of it as the "smallest possible width" for the screen). You can use this qualifier to ensure that, regardless of the screen's current orientation, your application's has at least <N> dps of width available for it UI. For example, if your layout requires that its smallest dimension of screen area be at least 600 dp at all times, then you can use this qualifer to create the layout resources, res/layout-sw600dp/. The system will use these resources only when the smallest dimension of available screen is at least 600dp, regardless of whether the 600dp side is the user-perceived height or width. The smallestWidth is a fixed screen size characteristic of the device; the device's smallestWidth does not change when the screen's orientation changes. The smallestWidth of a device takes into account screen decorations and system UI. For example, if the device has some persistent UI elements on the screen that account for space along the axis of the smallestWidth, the system declares the smallestWidth to be smaller than the actual screen size, because those are screen pixels not available for your UI. This is an alternative to the generalized screen size qualifiers (small, normal, large, xlarge) that allows you to define a discrete number for the effective size available for your UI. Using smallestWidth to determine the general screen size is useful because width is often the driving factor in designing a layout. A UI will often scroll vertically, but have fairly hard constraints on the minimum space it needs horizontally. The available width is also the key factor in determining whether to use a one-pane layout for handsets or multi-pane layout for tablets. Thus, you likely care most about what the smallest possible width will be on each device. |
Available screen width |
w<N>dp |
Specifies a minimum available width in dp units at which the resources should be used—defined by the <N> value. The system's corresponding value for the width changes when the screen's orientation switches between landscape and portrait to reflect the current actual width that's available for your UI. This is often useful to determine whether to use a multi-pane layout, because even on a tablet device, you often won't want the same multi-pane layout for portrait orientation as you do for landscape. Thus, you can use this to specify the minimum width required for the layout, instead of using both the screen size and orientation qualifiers together. |
Available screen height |
h<N>dp |
Specifies a minimum screen height in dp units at which the resources should be used—defined by the <N> value. The system's corresponding value for the height changes when the screen's orientation switches between landscape and portrait to reflect the current actual height that's available for your UI. Using this to define the height required by your layout is useful in the same way as w<N>dp is for defining the required width, instead of using both the screen size and orientation qualifiers. However, most apps won't need this qualifier, considering that UIs often scroll vertically and are thus more flexible with how much height is available, whereas the width is more rigid. |
雖然使用這些限定符可能看起來比使用屏幕尺寸分組彷佛更復雜,一旦肯定用戶界面的要求,它實際上應該是更簡單。當設計UI時,關心的主要事情是當應用程序在手機式UI和平板式UI之間遷移時它的實際尺寸。
更多關於尺寸配置限定符的討論,請參閱Providing Resources
配置實例
爲了您針對不一樣類型的設備進行設計,這裏是典型的屏幕寬度的一些數字:
320dp: 一個典型的手機屏幕 (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, 等).
480dp: 像Streak同樣的中立平板屏幕 (480x800 mdpi).
600dp: 7」平板 (600x1024 mdpi).
720dp: 10」平板 (720x1280 mdpi, 800x1280 mdpi, 等).
使用表2中的尺寸限定符,應用程序可使用任何您想要的寬度和/或高度爲手機和平板之間切換不一樣的佈局資源。好比,若是600dp是平板佈局所支持的最小可用寬度,能夠提供這兩套佈局:
res/layout/main_activity.xml # For handsets
res/layout-sw600dp/main_activity.xml # For tablets
在這種狀況下,爲了讓平板佈局實用,可用屏幕空間的最小寬度必須爲600dp。
要進一步定製UI區分大小,如7「和10」平板的狀況下,能夠定義額外的最小寬度佈局:
res/layout/main_activity.xml # For handsets (smaller than 600dp available width)
res/layout-sw600dp/main_activity.xml # For 7」 tablets (600dp wide and bigger)
res/layout-sw720dp/main_activity.xml # For 10」 tablets (720dp wide and bigger)
注意,前面的兩個例子資源使用「最小寬度」限定符,sw<N>dp,它指定屏幕兩邊的最小值,不管設備的當前方向。所以,使用sw<N>dp是簡單的經過忽略屏幕方向的方式來指定佈局的總體屏幕尺寸。
然而,在某些狀況下,可能重要的是佈局究竟有多大的寬度或高度目前是可用的。例如,有兩個並排的佈局,每當屏幕寬度至少提供600dp時使用,不論設備是不是在橫向或縱向。在這種狀況下,資源看起來像這樣:
res/layout/main_activity.xml # For handsets (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml # Multi-pane (any screen with 600dp available width or more)
請注意,第二組使用「可用寬度」限定符,w<N>dp。這樣,一臺設備可能根據屏幕的方向會使用這兩種佈局(若是可用寬度在一個方向至少600dp而在另外一個方向小於600dp)。
若是關注的是可用高度,那麼一樣可使用h<N>dp限定符。甚至能夠結合使用w<N>dp 和 h<N>dp 限定符。
聲明屏幕尺寸支持
一旦已經爲不一樣的屏幕尺寸實現了佈局,一樣重要的是在應用程序的manifest文件中聲明應用程序支持哪些屏幕。
隨着屏幕尺寸的新的配置限定符,Android 3.2引入了<supports-screens> 元素的新屬性。
android:requiresSmallestWidthDp
指定的最低寬度。 smallestWidth是指必須提供給應用程序的UI最短尺寸的屏幕空間(單位dp),也就是說,最短的可用屏幕的兩個維度。所以,爲了讓一個設備與應用程序兼容,設備的smallestWidth必須等於或大於這個值。 (一般狀況下,該值是佈局支持測「最小寬度」,不管當前屏幕的方向。)
例如,若是應用程序僅用於最小可用寬度是600dp的平板式設備:
<manifest ... >
<supports-screens android:requiresSmallestWidthDp="600" />
...
</manifest>
不過,若是應用程序支持Android支持的全部屏幕尺寸(如426dp x 320dp這麼小),那麼並不須要聲明這個屬性,由於應用程序須要的最小寬度在任何設備上都是最小的。
注意:Android系統並不關注這個屬性,因此它不會影響應用程序在運行時的行爲。相反,它被用於過濾應用程序,如Google Play(谷歌播放)。然而,目前谷歌播放不支持過濾(基於Android 3.2)這個屬性,因此若是應用程序不支持小屏幕,應該繼續使用其餘的大小屬性。
android:compatibleWidthLimitDp
這個屬性容許經過指定應用程序支持的最大"smallest width"來讓screen compatibility mode (屏幕兼容模式)成爲用戶可選的特性。若是設備的可用屏幕最小的一邊大於該值,用戶仍然能夠安裝該應用程序,但提供在屏幕兼容性模式運行。默認狀況下,屏幕兼容模式是無效的,並且佈局會去調整適應普通的屏幕,可是系統欄會提供一個按鈕來容許用戶切換屏幕兼容模式開關。
注:若是應用程序的佈局適當調整以適應大屏幕,則不須要使用這個屬性。建議避免使用這個屬性,而應當按照本文的建議確保佈局調整以適應大屏幕。
這個屬性容許經過指定應用程序支持的最大的"smallest width"來強制啓用 screen compatibility mode屏幕兼容模式。若是設備的可用屏幕最小的一邊大於該值,應用程序會強制運行在屏幕兼容模式,用戶沒法干預。
注:若是應用程序的佈局適當調整以適應大屏幕,則不須要使用這個屬性。建議避免使用這個屬性,而應當按照本文的建議確保佈局調整以適應大屏幕。
注意:爲Android 3.2及以上版本開發時,不該該使用上面列出的屬性結合舊的屏幕大小屬性。同時使用新屬性和舊屬性,可能會致使意想不到的行爲。
最佳實踐
支持多屏幕的目標是建立一個應用程序能夠正常而且很好地運行在Android支持的任何的廣義屏配置。前幾節提供有關Android是如何適應應用程序的屏幕配置,以及如何自定義應用程序在不一樣的屏幕配置上的展示。本節提供了一些額外的技巧和技術的概述,以幫助確保應用程序適配不一樣的屏幕配置。
這裏是一個有關如何能夠確保應用程序在不一樣的屏幕上正確顯示的快速清單:
當在XML佈局文件中定義尺碼時,使用 wrap_content, fill_parent, 或者 dp 單位
不要在應用程序代碼中使用硬編碼的像素值
不要使用 AbsoluteLayout (它已被廢棄)
爲不一樣的屏幕密度提供可選的位圖
如下部分提供更多細節。
1.當在XML佈局文件中定義尺碼時,使用 wrap_content, fill_parent, 或者 dp 單位
當爲XML佈局文件定義android:layout_width 和 android:layout_height時,使用"wrap_content", "fill_parent" 或者 dp單位,能夠確保視圖在當前屏幕上有一個合適的尺寸。
例如,一個layout_width="100dp"的視圖在中密度屏上佔用100像素,而在高密度屏上則是150像素,因此視圖在屏幕上佔用大約相近的物理空間。
一樣,應該更傾向於使用sp (scale-independent pixel)來定義文本大小。 sp 縮放因子和dp.同樣取決於用戶設置和系統縮放的大小。
2.不要在應用程序代碼中使用硬編碼的像素值
不做過多解釋。
若是應用程序操縱位圖或在運行時的像素值,請參閱Additional Density Considerations。
3. 不要使用 AbsoluteLayout
不一樣於其餘佈局部件,AbsoluteLayout強制使用固定的位置去擺放子視圖,這很容易致使在不一樣的顯示器的用戶界面不能好好工做。 正由於如此,AbsoluteLayout在Android 1.5(API等級3)被廢棄。
應該使用RelativeLayout,它使用相對定位來擺放子視圖。例如,能夠指定一個按鈕部件讓它顯示在文本部件的右側。
4. 使用基於尺寸和密度的資源
若是想嚴格控制應用程序在不一樣屏幕配置上的展現,那就在配置相關的資源目錄下調整佈局和圖片。例如,考慮到想要在中等和高密度顯示屏上用到的圖標,只需建立兩個大小不一樣(例如中密度的爲100x100,高密度的爲150X150)的圖標,並使用適當的限定放置在相應目錄下:
res/drawable-mdpi/icon.png //for medium-density screens
res/drawable-hdpi/icon.png //for high-density screens
注:若是目錄名中沒有定義密度限定符,系統假定該目錄中的資源爲基準密度而設計,並會爲其餘密度做適當擴展。
更多關於配置限定符的信息,請參閱使用配置限定符
關於密度的額外思考
本節將介紹更多的Android在不一樣的屏幕密度上如何處理位圖的縮放,以及如何能夠進一步控制位圖在不一樣屏幕密度上的繪製。本節信息對於大多數的應用程序是不重要的,除非在不一樣屏幕密度上運行應用程序時遇到問題或者應用程序須要操做圖像。
爲了更好地瞭解如何在運行時操做圖像時支持多密度,應該瞭解,系統有助於確保位圖的適當縮放,表如今如下方面:
預縮放資源 (好比 bitmap drawables)
基於當前屏幕的密度,系統不加縮放地使用應用程序的任何尺寸或密度相關資源。若是資源不是以正確的密度提供的,系統會加載默認的資源而且按須要根據當前屏幕密度進行縮放。系統假定默認資源(那些在沒有配置限定符的目錄下的資源)是爲基準屏幕密度(mdpi)設計的,除非他們是從一個特定密度的資源目錄加載。所以,預縮放就是系統爲當前屏幕密度進行適當的縮放資源。
若是請求預縮放資源的尺寸,系統將返回縮放後的尺寸。例如位圖,爲mdpi屏幕設計的50 x50像素的位圖在hdpi的屏幕上被放大到75x75像素,那麼系統報告的就是75x75像素。
有一些狀況下,可能但願Android不進行預縮放。避免預縮放的最簡單的方法,就是把資源放在以nodpi 配置限定符標識的目錄下,好比:
res/drawable-nodpi/icon.png
這樣,當系統選用該文件夾的icon.png位圖時,不會基於當前屏幕密度進行擴展。
像素尺寸和座標的自動縮放
應用程序能夠經過在manifest中設置android:anyDensity 爲「false」或者在程序中設置Bitmap的inScaled爲"false"這種來禁用預縮放。在這種狀況下,系統在繪製時自動調整任何絕對的像素座標和像素尺寸值。它這樣作,以確保像素定義屏幕元素仍然與在基準屏幕密度(mdpi)下顯示相近的物理尺寸。系統爲應用程序透明的處理這個比例而且報告縮放過的像素給應用程序,而不是物理像素尺寸。
一般狀況下,不該該禁用預縮放。支持多個屏幕的最好辦法是上文提到的如何支持多屏幕。
若是應用程序操縱位圖,或以一些其餘的方式與屏幕上的像素進行直接交互,可能須要採起額外的步驟,以支持不一樣的屏幕密度。例如,若是經過計算手機通過的像素數來響應觸摸手勢,則須要使用適當的密度無關的像素值,而不是實際像素。
在運行時建立的縮放位圖對象
Figure 5. 預縮放和自動縮放位圖的比較, 來自 ApiDemos.
若是應用程序建立一個內存位圖(Bitmap 對象),系統會假設該位圖是專爲基準密度屏幕設計的而且在繪製時進行自動縮放。系統當位圖有不明密度屬性時,將 「自動縮放」運用於一個Bitmap位圖。若是沒有正確地統計當前設備的屏幕密度,並指定位圖的密度屬性,自動縮放會致使縮放失真,就像沒有提供可選性資源同樣。
爲了控制在運行時建立的位圖是否被縮放,能夠用setDensity()來指定位圖的密度,經過傳遞一個來自DisplayMetrics的密度常量,好比DENSITY_HIGH 或者 DENSITY_LOW
若是使用BitmapFactory建立一個Bitmap ,如從一個文件或流,可使用BitmapFactory.Options來定義位圖屬性,該屬性決定了系統是否或者如何縮放位圖。
圖5演示了預縮放和自動縮放在高密度屏上加載低(120),中(160)和高(240)密度位圖的結果。差別是微妙的,由於全部位圖被縮放以匹配當前屏幕密度,可是縮放的位圖呈現細微的區別,這取決於它們在繪製時時預縮放的仍是自動縮放的。能夠在ApiDemos代碼中找到這個示例應用程序,它演示瞭如何使用預縮放和自動縮放位圖。
注: 在Android 3.0及以上版本,因爲在圖形架構的改進,預縮放和自動縮放位圖之間沒有可感知的差別,
dp單位轉換爲像素單位
在某些狀況下,須要用dp 來表示尺寸,而後將它們轉換爲像素。想象一個應用程序,當用戶手指移動至少16像素,則造成一個滾動或者拋擲手勢。在基準屏幕上,用戶必須在手勢造成以前移動16個像素/ 160 dpi,等於一英寸的十分之一(2.5毫米)。在高密度顯示器(240dpi)的設備上,用戶必須移動16個像素/ 240 dpi,這等於一英寸的十五分之一(1.7毫米)。距離要短得多,所以,應用程序彷佛對用戶更加敏感。
爲了解決這個問題,在代碼中手勢門檻必須用dp 來表示,而後轉化爲實際的像素。例如:
// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);
// Use mGestureThreshold as a distance in pixels...
DisplayMetrics.density域指定縮放因子,使用該縮放因子根據當前的屏幕密度來把dp 轉換爲像素。在一箇中等密度的屏幕上,DisplayMetrics.density等於1.0;在一個高密度的屏幕上,它等於1.5;在一個超高密度屏幕上,它等於2.0;在低密度屏幕上,它等於0.75。用dp乘以這個數字就獲得當前屏幕的實際像素數值。 (當轉換爲整數時,添加0.5f 四捨五入到最接近的整數)。有關詳細信息,請參閱的DisplayMetrics類。
然而,對這類事件,應該使用 ViewConfiguration預縮放的配置值,而不是定義一個任意的門檻。
使用預縮放的配置值
可使用ViewConfiguration 類訪問Android系統的通常的的距離,速度和時間。例如,能夠經過getScaledTouchSlop()得到框架使用的滾動門檻;
private static final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();
ViewConfiguration 類中以getScaled 爲前綴的方法能夠保證返回能夠正確顯示的像素值,不論當前的屏幕密度。
如何在多屏幕上測試應用程序
Figure 6. 用來測試屏幕支持的一組AVD。
發佈應用程序以前,應該在全部支持的屏幕尺寸和密度上進行完全的測試。 Android SDK中包含可使用的模擬器皮膚,它複製常見的屏幕配置的大小和密度,應用程序可能運行於這些皮膚。也能夠以任何特定的屏幕特色修改默認的大小,密度,和模擬器皮膚。使用模擬器的皮膚和額外的自定義配置,能夠測試任何可能的屏幕配置,而不用買各類設備。
爲了搭建一個測試應用程序屏幕支持的環境,應該建立一系列AVD(Android虛擬設備),使用模擬器的外觀和屏幕配置,模擬應用程序支持的屏幕尺寸和密度。這樣作,可使用AVD管理器建立AVDS,而後使用圖形界面啓動它們。
啓動Android SDK管理器,從Android SDK目錄執行SDK Manager.exe 的(僅適用於Windows)或從<sdk>/tools/ 目錄執行android (全部平臺)。圖6顯示了AVD管理器中的一組AVD。
表3顯示了Android SDK中的各類仿真皮膚,能夠用它來模擬一些最多見的屏幕配置。
欲瞭解更多有關建立和使用的AVD來測試應用的詳細信息,請參閱Managing AVDs with AVD Manager。
Table 3. Android SDK中模擬器皮膚提供的各類屏幕配置和典型的分辨率。
Low density (120), ldpi |
Medium density (160), mdpi |
High density (240), hdpi |
Extra high density (320), xhdpi |
|
Small screen |
QVGA (240x320) |
480x640 |
||
Normal screen |
WQVGA400 (240x400) |
HVGA (320x480) |
WVGA800 (480x800) |
640x960 |
Large screen |
WVGA800** (480x800) |
WVGA800* (480x800) |
||
Extra Large screen |
1024x600 |
WXGA (1280x800)† |
1536x1152 |
2048x1536 |
查看支持任何屏幕配置的活動設備的相關數值,請參閱Screen Sizes and Densities
Figure 7. 當從AVD管理器啓動AVD時,能夠設置的尺寸和密度選項
還建議在這樣的模擬器上去測試應用程序,此模擬器被配置爲物理尺寸和實際設備相近。這樣作,須要電腦顯示器的大概的DPI密度,(例如,30「戴爾顯示器具備大約96 dpi的密度)。當從AVD管理器啓動一個AVD時,能夠在Launch Options中爲模擬器和監視器指定dpi,如圖7所示。
若是想要在一個不被內置皮膚所支持的分辨率或者密度的屏幕上測試應用程序,能夠用自定義的分辨率和密度建立一個AVD。當從AVD管理器建立一個AVD時,定義分辨率,而不是選擇內置皮膚。
若是從命令行啓動AVD,可使用-scale例如選項來指定模擬器規模。例如:
emulator -avd <avd_name> -scale 96dpi
爲了細化模擬器的尺寸,能夠替代-scale選項爲一個0.1到3之間的數字,它表明指望的縮放因子。
注:本文譯自android開發者網站,原文請參考http://developer.android.com/guide/practices/screens_support.html