【官網翻譯】Android屏幕適配從原理到最佳實踐(很全的教程)

原文:http://developer.android.com/intl/zh-cn/guide/practices/screens_support.html

翻譯還比較粗糙,有一些地方難免不太通順,而且文檔難免繁瑣和複雜,如果想看精簡一點的移步:http://blog.csdn.net/program_thinker/article/details/41806135


Android運行在各種不同屏幕尺寸和密度的設備上,對於應用程序,Android系統提供了一個一致的跨設備的開發環境並且爲適應不同屏幕處理絕大多數的事情。同時,爲了應對更多特殊的屏幕,系統提供了各種API來優化你的應用程序界面。


雖然系統做了很多的擴展和調整,使你的應用程序能夠在不同的屏幕上工作,但是你也應該做出努力,以優化在不同的屏幕大小和密度設備上的應用程序的表現。在此過程中,你最大程度的爲所有設備增強用戶體驗,讓用戶體驗到你的程序是爲他們設備而作,而不僅僅是拉伸以適應設備屏幕。


按照文檔中描述的行爲,你可以使用一個apk文件創建提供支持所有屏幕配置並且顯示正常的應用程序。


注意:本文檔中信息假定你的應用程序爲Android1.6(API 4)以及更高的版本,如果你的應用程序支持Android1.5或者更低,請寫閱讀Android1.5的策略。

此外,要注意Android3.2引入了新的API,讓你能夠爲支持不同屏幕尺寸更精確控制使用的佈局資源來構建你的應用程序。這些新功能是特別重要的,如果你正在開發對於平板電腦的應用程序,請參閱有關聲明的平板佈局Android3.2部分。


屏幕支持的概述

本節提供了Android多屏幕支持的概述,包括:API介紹,屏幕配置,總結系統使用的術語和概念,以及屏幕底層的概述


術語與概念


屏幕尺寸
實際的物理尺寸,測量屏幕的對角線。
爲簡單起見, Android中的所有實際的屏幕尺寸分爲四個廣義大小:小,正常,大,和超大。

屏幕像素密度
屏幕的物理區域內的像素的數量:通常被稱爲dpi(每英寸點數) 。例如,在給定的物理區域內一個“低”密度屏幕比 “正常”或“高”密度屏幕具有較少的像素。爲簡單起見, Android中的所有實際的屏幕密度分爲六個廣義密度:低,中,高,超高,超超高,超超超高。

方向

從用戶的角度看到的屏幕方向。一般爲橫向或縱向,即屏幕的寬高比。注意,不僅要關注不同的設備在缺省情況下的屏幕方向。同一設備當用戶旋轉時,應用程序的屏幕方向也需要關注。


分辨率

在屏幕上的物理像素的總數。當爲多個屏幕添加了支持,應用程序不直接與分辨率相關:應用程序應只能與屏幕大小和密度有關,和指定的廣義的大小和密度基有關。


密度無關像素(DP)

虛擬像素單元。在定義UI佈局的時候,你應當使用與密度無關的方式來表示佈局尺寸或者位置

密度無關的像素相當於在一個160dpi屏幕上的一個物理像素。這是一個假定在“中等”密度屏幕的基線密度。在運行時候,系統透明的處理任何縮放的DP單位,根據需要轉化成屏幕的實際密度。dp的轉化屏幕實際像素比較簡單:px = dp * (dpi / 160)。例如,一個240dpi的屏幕上,1dp等於1.5的物理像素。定義你的應用程序UI的時候,你應該總是使用dp單位,以確保在不同密度的屏幕UI的正確顯示


屏幕支持的範圍

從Android 1.6 ( API 4 )開始, Android提供了多種屏幕尺寸和密度,反映了多種不同的設備可能支持屏幕配置。您可以使用Android系統的功能來優化您應用程序的用戶界面。對於每個屏幕配置,確保您的應用程序,不僅能夠正常呈現,而且提供了最佳的用戶體驗。

爲了簡化您設計針對多個屏幕的用戶界面的方法,Android把實際的屏幕尺寸和密度分成如下範圍:
一組(四個)廣義大小:小,正常,大和超大
一組(六種)廣義密度:
ldpi (低) 〜 120dpi
mdpi (中) 〜 160dpi
hdpi(高) 〜 240dpi
xhdpi (超高) 〜 320dpi
xxhdpi (超超高) 〜 480dpi
xxxhdpi (超特超高) 〜 640dpi


廣義的尺寸和密度圍繞一個正常大小和mdpi密度的基準配置。這個基準配置是基於第一個Android設備的屏幕,型號 T- Mobile G1 ,它有一個HVGA屏幕(直到安卓1.6 ,這是Android的唯一支持的屏幕配置) 。

每個廣義尺寸和密度跨越一系列實際屏幕尺寸和密度。例如,兩個設備都聲明瞭正常的屏幕大小但手工測量的實際的屏幕尺寸和縱橫比可能略有不同。同樣地,兩個設備都聲明瞭hdpi的畫面密度但實際的像素密度可能也略有不同。安卓爲應用程序抽象這些差異,根據你提供UI設計的廣義大小和廣義密度,讓系統按必要的情況做出調整。圖1示出了如何將不同的尺寸和密度大致地分類爲不同的尺寸和密度。


圖1.Android的粗略的廣義屏幕大小和密度 。

當你設計你的用戶界面以適配不同的屏幕尺寸,你會發現每一個設計都需要一個空間的最小量。所以,每個以上的廣義尺寸具有由系統定義的相關聯的最小分辨率。這些最小尺寸以“DP ”爲單位,在定義你的佈局時你應該使用dp爲單位,它允許系統不用擔心屏幕密度改變

  • 超大屏幕是至少960dp X 720dp
  • 大屏幕至少640dp X 480dp
  • 正常屏幕至少470dp X 320dp
  • 小屏幕至少426dp X 320dp
注意:這些最小的屏幕尺寸在Android3.0之前都沒有得到很好的定義 ,所以你可能會遇到一些設備在標準和大之間的錯誤分類。這也是基於屏幕的物理分辨率,因此可以跨設備,例如一款1024x720平板電腦實際上由於系統欄而減少了提供給應用程序的空間。

爲不同的屏幕尺寸和密度優化您的應用程序的UI,可以爲任何廣義大小和密度提供備選資源。通常情況下,你應該爲不同的屏幕尺寸提供可供選擇的佈局和爲不同的屏幕密度提供備選的位圖圖像。在運行時,系統根據當前設備屏幕的大小和密度爲您的應用程序使用適當的資源。


你不需要對屏幕尺寸和密度的各種組合提供備選的資源。系統提供了強大的兼容功能,可以處理你的應用程序在大多數設備屏幕上工作,前提是你使用能夠調整的技術(如最佳實踐說明,下同)實現您的UI。


注意:定義一個設備的屏幕尺寸和密度的特性是彼此獨立的。例如,一個WVGA高密度屏幕被認爲是一個正常大小的屏幕,因爲它的物理尺寸和T-Mobile G1大致相同( Android的第一臺設備和基準屏幕) 。另一方面,一個WVGA中密度屏幕被認爲是一個大尺寸屏幕。雖然它提供了相同的分辨率(像素數相同) ,所述的WVGA中密度屏幕具有較低的屏幕密度,這意味着每個像素在物理上是較大的,因此,整個屏幕比基線(正常大小)的屏幕大。


屏幕密度獨立

當你的應用實現了“密度獨立”時,從用戶的角度看,在不同密度屏幕顯示的用戶界面元素都保持了對應的物理尺寸(譯者注:就是用戶看起來不同屏幕體驗都一樣,這話說成這樣真是繞)


維持密度獨立性是很重要的,因爲如果沒有它,一個用戶界面元素(如按鈕)顯示在低密度屏幕上比顯示在高密度屏幕上在物理上更大。這樣的密度有關大小的變化可能會導致你的應用程序的佈局和可用性問題。圖2和3表明應用程序提供或者不提供密度獨立顯示的差異。


圖2:密度不獨立的應用程序,對不同密度屏幕的顯示效果


圖3:密度獨立的應用程序,對不同密度屏幕的顯示效果


Android系統可以幫助您的應用程序實現密度獨立兩種方式:

  1. 系統爲適合當前屏幕密度伸縮dp單位
  2. 系統根據當前屏幕密度擴展資源到合適的大小,如果需要的話
在圖2中,文本視圖和位圖資源的拉伸是以像素(px)爲單位的,所以我們看到的界面元素在低密度屏幕在物理上顯示更大和高密度屏幕物理上顯示更小。這是因爲,儘管實際的屏幕尺寸可以是相同的,在高密度屏幕上具有每英寸更多的像素。在圖3中,佈局尺寸是由密度無關像素( dp)指定。因爲密度無關的像素是以一箇中等密度的屏幕爲基線的,所以它和圖2中具有中等密度屏幕上看起來相同。對於低密度和高密度的屏幕,系統分別向下和向上的擴展密度無關像素值,以適應對應屏幕。

在大多數情況下,你可以確保你的應用程序密度的獨立性只需通過密度無關像素( dp單位)或“ WRAP_CONTENT ”來規定所有的佈局尺寸值。然後,系統根據當前屏幕的密度相應的縮放因子酌情擴展位圖以顯示在適當的大小。

然而,你可能在上面的截圖中看到,位圖縮放可能會導致模糊或像素化的位圖。爲了避免這些問題,就應該針對不同的密度提供備選位圖資源。例如,你應該爲高密度顯示屏提供更高分辨率的位圖,系統將使用這些代替專爲中等密度的屏幕的位圖。以下部分介紹了更多關於如何爲不同的屏幕配置提供備選資源。

如何支持多屏幕
Android的多屏幕支持的基礎是它能夠根據當前屏幕配置以適當的方式管理提出申請的佈局和位圖渲染能力。系統處理的大部分工作是以適應屏幕尺寸/密度縮放佈局和擴展位圖以適應屏幕像素密度。但是,爲了更加妥善地處理不同的屏幕配置,你也應該:

在manifest中顯示聲明應用程序支持的屏幕尺寸清單
通過聲明應用程序支持的屏幕尺寸,可以確保你支持的屏幕的設備可以下載你的應用。通過聲明支持不同屏幕的尺寸還可以影響系統如何在大屏幕上繪製你的應用程序,特別的,應用程序是否在屏幕兼容模式下運行。聲明應用程序支持的屏幕尺寸,你應該在你的manifest文件包括<supports-screens>元素。

爲不同的屏幕尺寸提供不同的佈局
默認情況下, Android系統重新調整你的應用程序佈局以適應當前設備的屏幕。在大多數情況下,這工作的很好。但在有些情況下,你的UI可能看起來不那麼好,可能需要調整不同的屏幕尺寸。例如,在大屏幕上,您可能需要調整一些元素的位置和大小以充分利用屏幕空間的優勢,或者在一個較小的屏幕上,你可能需要調整大小,使一切都可以容納在屏幕上。
根據配置限定符,你可以用它來提供大小的特定資源,比如小,正常,大和超大 。例如,超大屏幕布局應該在文件夾layout-xlarge /下面 。
從Android 3.2 ( API等級13 )起,上述尺寸組已過時,應改用sw <n > dp配置限定符來定義你的佈局資源所需的最小可用寬度。例如,如果你的平板電腦的佈局至少需要600dp屏幕寬度,你應該把它放在文件夾layout-sw600dp /下 。在有關平板佈局的聲明在Android 3.2節進一步討論。

爲不同的屏幕密度提供不同的位圖資源
默認情況下, Android的擴展位圖資源包括(.png,.jpg和.gif文件)和九補丁資源( .9.png文件) ,它們以適當的物理尺寸呈現在每個設備上。例如,如果你的應用程序只爲基準屏幕(中屏幕像素密度mdpi)提供的位圖資源 ,那麼在高密度屏幕上的時候系統會擴展它們,並在低密度屏幕上的時候系統縮放它們。這個縮放可能會影響位圖。爲確保您的位圖看起來是最好的,你應該包括不同屏幕密度和不同分辨率備選版本。
根據配置的限定符,你可以使用密度特定的資源,包括ldpi(低),mdpi(中),hdpi(高),xhdpi(超高),xxhdpi(超超高)和xxxhdpi(超超超高)。例如高密度屏幕位圖資源應該放在文件夾drawable-hdpi/下
注意:drawable-xxxhdpi限定符僅需要提供給比xxhdpi設備上的launcher的圖標,你並不需要爲所有的應用程序提供xxxhdpi資源。
某些設備需要向上擴大25%的launcher的圖標,例如如果你的最高密度的launcher的圖標已經是xxhdpi的密度,在xxxhdpi上顯得不那麼清晰,那麼最好提供xxxhdpi的繪製目錄

注意:如果你不熟悉的配置限定符和系統如何使用這些備選資源,閱讀提供備選資源(http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources)以獲取更多信息。

在運行時,通過下列步驟系統確保當前屏幕的最佳可能顯示:
1、系統採用了合適的備選資源
基於當前屏幕的尺寸和密度,系統使用應用程序提供的適合大小與密度相關的資源。例如,如果該設備具有高密度的屏幕,當應用程序請求繪製資源,系統尋找最匹配該設備配置的可繪製的資源的目錄。根據現有的備選資源,hdpi限定符目錄下的資源(如drawable - hdpi/ )可能是最好的匹配,因此係統採用這個目錄中的資源進行繪製。
2、如果沒有匹配的資源是可用的,則系統將使用默認資源向上或向下按需要縮放以匹配當前的屏幕尺寸和密度
“默認”資源是那些不具有標記的結構限定符。例如,在drawable/目錄下的資源是默認繪圖資源。系統假定默認資源被設計爲基線屏幕大小和密度,這是一個正常的屏幕尺寸和中等密度。這樣,系統爲高密度屏幕向上放大缺省資源或者爲低密度資源向下縮小資源。
然而,當系統正在尋找一個特定密度的資源,並且沒有發現它在特定密度的目錄中時,也不會總是使用默認資源。系統可改用其他密度相關的資源之一,爲了縮放時提供更好的結果。例如,沒有找一個低密度資源時,系統傾向於按比例縮減高密度版本的資源,因爲系統可以很容易地根據0.5因子向下縮放高密度資源到低密度,並且產生更少的模糊,相比根據0.75的因子縮放中等密度的資源。

使用配置限定符
Android支持多種配置限定符,使你可以控制基於當前設備屏幕的特性,決定系統如何選擇你的備選資源。一個配置限定符是在你的Android項目中可以追加到一個資源目錄,並指定裏面資源的設計配置的字符串。

使用配置限定符
1、在項目的res/目錄下面創建一個新的目錄,並使用以下格式命名:<resources_name>-<qualifier>。
  • <resources_name>是標準的資源名稱(例如drawable或者layout)。
  • <qualifier>是表1的結構限定符。指定這些資源將被哪種屏幕配置使用(比如hdpi和xlarge)。
你可以一次使用多個<qualifier>標籤,需要用破折號分隔。

2、在這個新的目錄中保存相應的配置資源。資源文件必須與默認資源文件命名完全相同。
例如,xlarge是一個配置超大屏幕的限定符,當這個字符串添加到一個資源目錄名中(如layout-xlarge),它指示系統,這些資源將在具有超大屏幕的設備中使用

表1:配置限定符,是你可以爲不同屏幕配置特定的資源


例如,以下是資源的目錄中,爲不同的屏幕尺寸提供了不同的佈局設計以及用於中密度,高密度及超高密度的屏幕的不同位圖資源的應用程序的列表。
res/layout/my_layout.xml              // layout for normal screen size ("default")
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
res/drawable-xxhdpi/my_icon.png       // bitmap for extra-extra-high-density
請注意,當Android系統選擇將哪些資源在運行時使用時,它使用一定的邏輯來決定“最佳匹配”的資源。也就是說,你的限定符可以不必在所有情況下都匹配當前的屏幕配置。具體地,如果基於當前尺寸沒有資源限定符很好的匹配的時候,系統會選擇使用比當前屏幕小的資源(例如,如果必要的話,一個大尺寸屏幕會使用普通大小的屏幕資源) 。然而,如果唯一可用的資源比當前的大,如果沒有其他的資源相匹配的設備配置,系統將不會使用它們(例如,如果所有的資源佈局都標記XLARGE限定符,但設備是一個正常大小的屏幕)應用程序會崩潰。有關係統如何選擇資源的更多信息,請閱讀安卓如何查找最佳匹配資源(http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch)。
(譯者注:經過實驗,尺寸從下往上適配,密度從上往下適配)

提示:如果你有一些繪製資源不應該由系統擴大(也許是因爲你在運行時對一些圖像進行一些調整) ,你應該把它們放在nodpi配置限定符的目錄。與此限定符相關資源被認爲是密度無關,系統將不會擴展它們。

設計可備選的佈局和繪圖資源
你應該根據應用程序的需要創建備選資源。通常情況下,你應該使用大小和方向限定符來創建備選佈局資源和使用密度限定符來創建備選位圖繪製資源。

以下各節分別概述了你可能想使用的大小和密度限定符創建備選佈局和繪圖資源。

可選的佈局
通常情況下,一旦你在不同的屏幕配置測試你的應用程序,你就會知道你是否需要爲不同的屏幕創建屏幕尺寸替代佈局。
  • 當在小屏幕上進行測試時,你可能會發現,你的佈局並不完全適合在該屏幕上。例如,一排按鈕未必適合在一個小屏幕設備上的寬度內。在這種情況下,你應該爲小屏幕的替代佈局調整按鈕的大小或位置。
  • 當在一個特大屏幕上進行測試時,你可能會意識到你的佈局不能有效地利用大屏幕,並且界面元素明顯拉長以填補它。在這種情況下,你應該有針對性地重新設計一個超大屏幕的替代佈局。雖然你的應用程序在不使用大屏幕替代佈局的時候也應該正常工作,但在用戶看來,你的應用程序看起來好像是爲他們的設備專門設計是非常重要的。如果UI明顯拉長,用戶的應用體驗更可能是不滿意的。
  • 並且,與縱向測試相比,橫向的時候,你可能會注意到,放置在縱向屏幕底部的UI元素應該放置在橫向屏幕的右側
總之,你應該確保你的應用程序佈局:
  • 適合在小屏幕上(這樣用戶可以實際使用應用程序)
  • 對於更大的屏幕優化,充分利用額外的屏幕空間的優勢
  • 優化橫向和縱向兩個方向
如果你的UI需要使用適配系統已經拉伸佈局之後的位圖(比如一個按鈕的背景圖片),你應該使用九補丁位圖文件(Nine-Patch)。九補丁文件一種Png文件,它只在你指定二維區域內可拉伸。當系統需要按比例繪製位圖時候,該系統拉伸九補丁位圖,但拉伸的只有指定的地區。因此,你不需要爲不同的屏幕尺寸提供不同的可繪製資源,因爲九補丁文件可以調節到任何尺寸。但是,你應該提供九補丁文件的不同的屏幕密度替代版本。

可選的繪圖資源
幾乎每一個應用程序應該有不同的屏幕密度替代繪製的資源,因爲幾乎每個應用程序都有一個啓動圖標,該圖標就應該在所有的屏幕密度很好看。同樣,如果你在應用程序中其他的位圖可繪製資源(如菜單圖標,或在應用程序中其他圖形) ,您應爲不同的密度提供替代版本。

注意:您只需要提供密度相關的可繪製的位圖文件(.png ,.JPG或.gif )和九補丁文件( .9.png ) 。如果你使用XML文件來定義形狀,顏色,或其他可繪製資源,你應該把一個副本放在默認繪製目錄(drawable/ )。

要爲不同密度創建替代可繪製的位圖,你應該按照3 : 4 : 6 : 8 : 12:16這6種廣義密度之間的縮放比例。例如,如果你有一個位圖繪製這是48×48像素的中等密度的屏幕,所有不同尺寸應該是:

  • 36x36 (0.75x) for low-density
  • 48x48 (1.0x baseline) for medium-density
  • 72x72 (1.5x) for high-density
  • 96x96 (2.0x) for extra-high-density
  • 180x180 (3.0x) for extra-extra-high-density
  • 192x192 (4.0x) for extra-extra-extra-high-density (launcher icon only; see note above)

圖4 不同密度的位圖相對大小

有關設計圖標的詳細信息,請參閱圖標設計指南(http://developer.android.com/guide/practices/ui_guidelines/icon_design.html),其中包括各種位圖大小信息,如Launcher的圖標,菜單圖標,狀態欄圖標,圖標標籤,以及更多。

聲明平板佈局(Android 3.2)
對於第一代運行Android 3.0平板電腦,正確的方法來聲明平板電腦的佈局是把它們放在一個目錄爲xlarge配置限定符中(例如, res/layout-xlarge / ) 。爲了容納其他類型的平板和屏幕的尺寸,特別是,7“的平板,Android3.2引入了一種新的方式來爲多個分立的屏幕尺寸指定資源。這種新技術的基礎是空間佈局需要的量(如600dp寬度) ,而不是試圖讓你的佈局符合廣義尺寸組(如large或xlarge ) 。

當使用廣義尺寸組爲7寸平板進行設計時非常棘手,因爲7寸平板在技術上與5寸的手持設備是屬於同一組(large)。而且這兩種設備大小也彼此接近,但用於應用程序UI的空間量和用戶交互方式明顯不同。所以7寸平板和5寸手持設備屏幕不應該總是使用相同的佈局。爲了讓你可以爲這兩組類型的屏幕提供不同的佈局,Android現在允許你根據寬度或者高度指定你的資源來適配你的實際應用佈局,指定dp爲單位

例如,在你爲平板樣式的設備設計好佈局之後,你也許才確定這個佈局在小於600dp的寬度屏幕上無法運行良好。這個門檻也隱藏成爲你需要爲你的平板電腦佈局的最小尺寸。因此,你現在可以指定只有至少有600dp的寬度時這些佈局可以爲你的應用程序UI使用。

所有你應該選擇一個寬度設計作爲你的最小尺寸,或者測試什麼是你佈局支持的最寬度。

注意:請記住,所有這些新的API的單位都使用屏幕無關像素(dp)以及佈局方面也始終使用dp單位定義,因爲你在乎的只是屏幕的可用空間(相對於使用原始像素分辨率)。

使用新的大小限定符
不同的資源配置,你可以指定表2中基於可用的佈局空間的限定符,這些新的限定符將爲你提供更多的控制特定屏幕尺寸應用程序支持,相比於傳統屏幕尺寸組(小,正常,大,以及超大)

注意:你指定使用的這些限定詞的大學不是實際屏幕的尺寸。相反,這些尺寸是以dp爲單位的寬或者高提供給你的activity窗口使用。Android系統也許使用一些作爲系統UI(比如屏幕頂部的狀態欄或者底部的系統欄),所以一些屏幕不能爲你的佈局所用。因此,你聲明的大小應該是你的activity所需要的。同時要注意,操作欄被認爲是應用程序窗口的一部分,儘管你的佈局不聲明它,但是其減少了可用的空間佈局,你必須在設計中考慮它。

表2:關於屏幕大小的新配置限定符(Android 3.2)







雖然使用這些限定詞似乎比使用屏幕尺寸組更加複雜,但實際上應該更簡單,一旦你確定了你的UI需求。在你設計UI的時候,你可能更關心在實際尺寸下使用哪種風格界面,是平板式的多個窗格,還是手機的單窗格樣式。
這種轉換的確切點取決你的設計,也許你需要一個720dp寬度的平板電腦佈局,也許600dp就夠了,或者480dp。或者他們之間的一些數字。使用以上的限定詞,你用精確的尺寸來控制佈局的變化。

配置實例
爲了幫你設計適合不同類型設備的屏幕,這裏有一些典型的屏幕寬度

  • 320dp: 一款典型的手機屏幕 (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).
  • 480dp: 一般的平板 (480x800 mdpi).
  • 600dp: 7” 平板 (600x1024 mdpi).
  • 720dp: 10” 平板 (720x1280 mdpi, 800x1280 mdpi, etc).
使用表2的新限定符,你的應用程序可以在手機和平板電腦之間切換使用不同的佈局資源,如果600dp是平板電腦佈局支持的最小可用寬度,你可以提供兩套佈局:

res/layout/main_activity.xml           # 對手機
res/layout-sw600dp/main_activity.xml   # 對平板
在這種情況下,對於使用平板佈局所需的最小寬度必須是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是忽略屏幕的方向指定整體屏幕尺寸可供佈局的簡單方法。

如果你關注屏幕的可用高度,那麼你可以使用h<N>dp限定符來做,或者你需要更加的具體化屏幕的方向,同時使用w<N>dp和 h<N>dp 兩個限定符。

聲明屏幕尺寸的支持
一旦你實現了支持不同屏幕尺寸的佈局,在manifest文件中聲明你應用支持的屏幕尺寸也是一樣重要
隨着新的配置限定符選項,Android3.2推出<supports-screens>的manifest新元素屬性。

指定所需的最小的寬度。smallestWidth是提供給你應用程序用戶界面的屏幕空間的最小尺寸(以dp爲單位),也就是說,在兩個維度上的最短可用屏幕。所以,爲了使一個設備被認爲是應用程序兼容的,該設備的smallestWidth必須等於或者大於改值。(通常情況下,無論屏幕的當前方向,你的佈局支持的這個最小寬度這個值)
例如,如果你的應用僅適用於具有600dp最小寬度可用平板式設備:

然而,如果你的應用所安裝的所有屏幕尺寸都小於426dp x 320dp,那麼你並不需要聲明這個屬性,因爲你應用程序所需要的最小寬度不可能在任何設備上。

此屬性允許你使用指定最大的“最小寬度”,使你的應用程序支持的屏幕兼容模式爲用戶可選功能。如果設備的可用屏幕最小邊大於這個值,用戶仍然可以安裝應用程序,但是在提供的屏幕兼容模式運行它。默認情況下,屏幕的兼容模式被禁止。你的佈局像往常一樣調整大小以適應屏幕,在系統欄的按鈕可以允許用戶切換屏幕兼容模式的開關。
注意:如果你的應用程序的佈局大小能夠適應大屏幕,我們建議你避免使用這個屬性,而是確保你按文檔爲大屏幕構建佈局

這個屬性可以讓你指定最大的“最小寬度”,你的應用程序支持強制啓用兼容模式(注意,這是以上一個屬性的區別,上一個用戶選項,這裏是強制)。如果設備的可用屏幕的最小邊大於你的這裏的值,應用程序沒有辦法爲用戶禁用這個兼容模式。
注意:如果你的應用程序的佈局能夠適應大屏幕,我們不建議你使用這個屬性。

注意:在開發針對Android3.2以及更高版本時,你不應該使用上面列出的屬性組合,同時使用新屬性和舊的屏幕尺寸屬性可能會導致意外的行爲。


最佳實踐
支持多屏的目標是創建一個能夠正常運行,並能在任何Android支持的屏幕配置上好看的應用程序。本文檔的前面幾節提供了有關Android如何適應你的應用程序的屏幕設置,以及如何自定義不同的屏幕配置的應用程序外觀信息。本節提供一些額外的技巧和技術,幫助你的應用程序適應不同的屏幕配置。

這裏是確保你的應用程序在不同屏幕上快速正確顯示的清單:
  • 在XML佈局文件中指導尺寸時,使用wrap_content,fill_parent或者dp單位
  • 不要在你的應用程序代碼中使用硬編碼的像素值
  • 不要使用AbsoluteLayout(不建議使用)
  • 提供備用的位圖來繪製不同屏幕密度的圖像

以下爲更詳細的說明

1.使用WRAP_CONTENT , FILL_PARENT或DP單元佈局尺寸
當定義XML文件屬性android:layout_width 和 android:layout_height時,使用"wrap_content"和"fill_parent"或者dp單位的值,確保視圖在目前設備上有一個適合的尺寸

例如,對於一個layout_width=“100dp”的圖,在中密度屏幕上佔據100像素寬度而在高密度屏幕上擴展到150個像素,以使圖在屏幕上佔據大致相同的物理空間

同樣的,你應該使用sp來定義文字的大小,這個sp比例因子依賴於用戶設定,系統將擴展它爲dp大小。


2、不要在你的應用程序代碼中使用硬編碼的像素值

出於性能的考慮,併爲了保持代碼簡單,Android系統使用像素值作爲表達維度或者座標的標準單位。這意味着,一個視圖的尺寸在代碼中始終是用像素表示的,但這是根據當前屏幕的像素密度。例如,如果myView.getWidth()返回是10,那麼認爲是在當前屏幕上的10個像素,如果在具有較高密度屏幕的設備上,這個返回值可能是15。如果你應用程序代碼使用像素值來處理沒有縮放適配當前屏幕的位圖,那麼你可能需要在代碼中縮放位圖資源的像素值來適配當前屏幕。


3、不要使用AbsoluteLayout

不像其他的窗口布局小部件,AbsoluteLayout強制使用固定的位置來佈置其子視圖,這很容易導致用戶界面在不同的屏幕上無法很好工作,因此AbsoluteLayout在Android1.5(API 3)已經過時。

你應該使用RelativeLayout,它對子視圖使用相對的位置,例如你可以指定一個按鈕控件出現在一個文本小部件的右邊(“to the right of”)


4、使用大小和密度特定的資源

雖然系統可以根據當前屏幕配置的繪製資源擴展你的佈局。但你仍然要爲不同的屏幕尺寸的用戶界面,提供不同密度優化的位圖資源。這基本上是重申了本文檔早期的信息

如果你需要精確的控制你的應用程序在不同屏幕配置的佈局,調整特定資源目錄中的佈局和位圖,例如,假設你要顯示中,高密度的屏幕圖標,簡單的創建兩個不同大小的圖標(例如100x100中密度和150x150高密度),並放在適當的目錄中,使用適當的限定符:

res/drawable-mdpi/icon.png   //for medium-density screens
res/drawable-hdpi/icon.png   //for high-density screens
注意:如果在目錄名中沒有定義密度限定符,那麼系統將假定該目錄中的資源是爲中密度基線所準備的並會將其擴展以適應其他的密度


附加的密度注意事項

本節將介紹更多關於Android系統如何在不同屏幕上擴展位圖資源和你如何在不同的像素密度上更進一步的控制位圖的繪製。本節的信息,對於大多數應用程序不是非常重要,除非你在不同屏幕密度下運行或者你的應用程序在操作圖形的時候遇到問題。

爲了更好的理解怎麼能夠在運行操作圖形時支持多種密度,你應該明白系統如何通過以下方式確保位圖適當的伸縮

1、預縮放資源(比如位圖資源)

基於當前的屏幕密度,系統使用你應用程序的任何大小或者特定密度的資源不進行縮放的顯示它們。如果資源在當前密度不可用時,系統會加載默認資源並且根據匹配當前密度的需求適當縮放它們。系統假設默認資源(沒有配置限定符文件夾下的)是專爲基準屏幕像素密度而準備,除非他們從有特定密度相關的資源目錄下加載。預縮放就是系統重新調整位圖的大小從而適應當前的屏幕。

如果你請求預縮放資源的尺寸,系統會返回縮放後的尺寸值。例如,在mdpi上設計的一個50x50do的位圖在hdpi的屏幕上會被縮放到75x75dp(如果沒有應用與hdpi的備選資源)

有些情況下,你可能不希望Android預縮放資源。避免預縮放資源的方法很簡單,就是創建使用nodpi爲限定符的資源目錄,如下所示

res/drawable-nodpi/icon.png
當系統使用該目錄下的位圖時,系統不會基於當前屏幕像素密度縮放它。

2、自動縮放尺寸和座標

應用可以在manifest文件中設置android:anyDensity="false"來禁止使用預縮放,或者編碼設置位圖資源的屬性“isScaled”禁用預縮放。在這種情況下,系統在繪圖時會自動縮放任意絕對像素座標和像素尺寸值。這樣做是爲了確保像素定義的屏幕元素顯示合適的物理尺寸。系統爲應用程序透明的處理這個縮放並且報告縮放的像素尺寸給應用程序,而不是物理像素尺寸。

例如,假如一臺設備具有一個480x480dp的WVGA高密度屏幕同時尺寸和傳統的HVGA屏幕相同。運行的應用程序禁止了預縮放功能,在這種情況下,當查詢屏幕尺寸的時候系統會依據應用,並報告320x533(近似mdpi的屏幕密度),當應用程序進行繪製操作的時候,比如畫一個從(10,10)到(100,100)的長方形時,系統會根據合適的量縮放座標,可能實際畫的區域是從(15,15)到(150,150)。如果你的應用程序直接操作縮放位圖,這種差異可能導致意外的行爲。但是爲了保持應用程序更好的表現,這被認爲是一個合理的權衡。

通常情況下,你不應該禁用預縮放。支持多屏的最好方法是遵循上訴的基本技術。


如果你的應用程序操作位圖或者以其他的方式與屏幕上的像素直接進行交互,你可能需要採取更多的措施來支持不同屏幕密度。例如,如果你通過手勢計算手指穿過的像素數量,你需要使用密度獨立的虛擬像素而不是實際像素值。


運行時縮放位圖對象

如果你的應用程序創建了一個內存中的位圖(一個bitmap對象)時,系統假設這個位圖是爲中密度的屏幕設計的。默認情況下,繪製的時候自動縮放這個位圖。當位圖沒有特殊的密度特性時,系統對位圖提供自動縮放。當你沒有正確考慮設備的屏幕密度和指定位圖的密度特性,自動縮放可能導致不好的效果當你不提供可替代的資源。

要控制運行時創建的位圖是否縮放, 你可以使用setDensity()函數指定位圖的密度,從DisplayMetrics傳遞一個密度,比如DENSITY_HIGH或DENSITY_LOW

如果你使用BitmapFactory(比如文件或者流)來創建位圖,你可以使用BitmapFactory.Options來定義位圖的屬性,這可以確定是否和如何讓系統縮放它。例如,你可以使用inDensity字段來位圖的密度是否被設計和inScaled字段來指定位圖是否應該縮放以匹配當前設備的屏幕密度。

如果你設置inScaled字段是false,那麼你禁用任何縮放,系統將會自動縮放,使用自動縮放比預縮放可能更耗CPU,但使用較少內存。

圖5:預縮放和自動縮放的位圖比較



圖5表明在高密度屏幕上加載低(120dp),中(160dp),高(240dp)密度的位圖時預縮放和自動縮放的結果,差異是微小的,因爲所有的位圖都被縮放以匹配的當前的屏幕密度,但是略有不同的外觀,這取決於是否是預縮放或者自動縮放的。

注意: 在Android3.0及以上,由於圖形框架的改善,預縮放和自動縮放位圖之間沒有明顯差異。


轉化dp單位到px單位

在某些情況下,你將需要的dp尺寸轉化爲像素尺寸。想象一個滾動或者手勢滑動應用,用戶手指必須移動至少16個像素才能被識別,在基準屏幕上,一個用戶必須移動16px/160dpi,等於1/10英寸(2.5毫米)纔會被識別。而在一個高密度設備上(240dpi),用戶只需要移動16px/240dpi,相當於1/15英寸(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單位轉化爲px單位的比例因子。在中等密度的屏幕,DisplayMetrics.density等於1.0;高密度等於1.5;超高密度的比例因子爲2.0;在低密度時,它等於0.75.你的當前dp值必須成語這個數字才能得到當前屏幕的實際像素值(添加0.5f然後將其轉換爲最接近的整數)。有關的詳細信息,請參閱DisplayMetrics這個類。


使用預縮放的配置值

你可以使用ViewConfiguration這個類去訪問通常的距離,速度和Android系統的時間。例如,框架所使用的滾動閾值的像素距離可以用getScaledTouchSlop()函數獲得:

private static final int GESTURE_THRESHOLD_DP = ViewConfiguration.get(myContext).getScaledTouchSlop();

如何測試你的應用在多個屏幕上的表現
在發佈你的應用程序之前,你應該徹底在它所有支持的屏幕密度和尺寸的設備上測試。Android SDK中包含了你可以使用的模擬器,它是複製了常見的密度和尺寸大小的仿真樣式機,你也可以調整模擬器的尺寸和密度。所以你可以通過使用模擬器而不必爲了你的應用程序屏幕支持而購買各種設備。

圖6:一套爲測試屏幕支持的模擬機


要創建測試你的應用程序的屏幕支持的環境,你必須創建一系列模擬機(Android虛擬設備)。模仿出你喜歡你的應用程序支持的屏幕大小和密度。要做到這點,你可以使用AVD管理器創建他們。

爲運行Android SDK管理器,打開你Android SDK目錄下的執行文件manage.exe(僅在Windows上),或者從<sdk>/tools/directory(所有平臺)執行android。圖6顯示了AVD管理一系列的AVDs

表3顯示了Android SDK顯示的各種仿真機型,你可以用它來模擬一些常見的屏幕配置。

有關創建和使用AVD來測試您的應用程序,更多信息請看http://developer.android.com/tools/devices/managing-avds.html

表3:Android SDK中各種屏幕配置模擬器



我們還建議你設置緊密匹配你實際設備物理尺寸的模擬器來運行你的程序,這讓它的測試結果更加可靠。爲了做到這點,你必須知道你的電腦顯示器的大致的密度(dpi),比如,一個30“戴爾顯示器擁有96dpi的密度。當你從AVD管理器啓動一個AVD,你可以指定模擬機的屏幕,並啓動顯示器DPI選項,如圖7


圖7:啓動AVD時設置大小和密度


當你的想測試的屏幕尺寸或者密度內置的機型不支持,你可以創建一個自定義分辨率或者密度的AVD,當你從AVD管理器中創建AVD時候,指定而不是選擇一個分辨率(或者密度)。


如果你用命令行啓動AVD,你可以使用-scale選項來指定模擬器的scale。例如:

emulator -avd <avd_name> -scale 96dpi

有關通過命令行創建AVD的更多信息,請參閱http://developer.android.com/tools/devices/managing-avds-cmdline.html


OVER

啃下來真是累。。。廢話太多準備總結一下出點乾貨

還有英文有限,翻譯的不好的地方請大家指正

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