第一部分:開發前的準備-第四章 多分辨率多屏幕的支持

第4章 多屏幕多分辨率的支持

若是你買過Android手機的話,銷售員通常會向你推薦這個android手機是最新版的系統啦,屏幕有多大,分辨率是多少之類的。這只是外表上的多屏幕和多分辨率,其實android內在還有一些影響因素,例如「密度」的概念。本章爲詳細的爲你解釋一些基礎概念並適當的舉一些例子教你怎麼處理關於多屏幕多分辨率的支持。 雖然Android系統內置有一些機制能使用多屏幕多分辨率,但咱們仍是應該在加點外力來更加優化用戶體驗的效果。android

4.1多屏幕支持概述

4.1.1基本術語和概念瀏覽器

屏幕大小eclipse

根據屏幕對角線實際測量的物理大小(android已經根據屏幕大小分爲四類small, normal, large, extra large)工具

屏幕密度佈局

屏幕物理區域一個單位(通常用英寸)的像素數量,通常簡稱dpi(‘dots per inch’每英寸中包含的點的數量,記住DPI這個概念很重要)學習

這裏android也分爲四類 low, medium, high, extra high.測試

方向優化

從用戶的角度看設備只有兩個方向,那就是橫屏和豎屏。關於橫豎屏最好也要出一套相對應的UI,由於長寬比不同,特別是對於軟件項目通常都是出兩套(遊戲通常都會鎖定一個方向)。編碼

分辨率spa

一個物理屏幕上像素點的總數。通常咱們的應用不會直接使用分辨率,而是使用密度和屏幕大小(但某些特殊狀況下,能夠指定分辨率)

獨立密度像素(Density-independent pixel ‘dip’)

一個虛擬的單位,用來定義UI佈局的。它是表述佈局的尺寸大小或者位置。

dip(注 意dip是獨立像素單位,dpi是屏幕密度)等價於一個160dpi(medium密度)的屏幕,運行時系統會根據你實際屏幕的密度來自動處理縮放。像素和dip 的轉換公式爲px =dp*(dpi/160) 。例如在240密度的屏幕上一個dp等於1.5個像素(dp=px*1.5)。之後咱們應該儘可能使用dip單位佈局,不要使用像素單位。這樣會使你的應用屏幕兼容性更好。最後咱們應該區分dpi和dip它們一個字母的不一樣表明的意思就不同。之後程序中咱們通常使用dp來代替dip用來描述位置和尺寸大小,而dpi則是屏幕密度,這裏你們須要稍微留心一下。下面咱們來舉個遊戲的例子:

關於android多屏幕多分辨率這道門檻,咱們能夠把它當作一個boss,要打敗這個boss咱們須要瞭解它的5個弱點(也能夠理解成遊戲套路)

  1. 屏幕大小---boss的體型,boss都有體型之分的,例如WOW中的BOSS大部分都是巨型,而有些遊戲中的boss比較小,例如劍網3的boss就比較小。
  2. 屏幕密度---boss的模型細粒度,有些boss你能看清它的每一個外觀細節,但有些boss就比較模糊,雖然你的電腦顯卡或者遊戲模型的材質會影響外觀細節。但請忽略它們!
  3. 方向---這個要以咱們的角度來觀察boss才能得出結論,例如你靠近boss並站在高處和你遠離boss站在低處看boss徹底是兩個感受。
  4. 分辨率---這個能夠理解爲對boss整體的外觀和風格,它是由boss的體型和boss的模型細粒度加在一塊兒體現出的一種外觀和風格,因此說分辨率咱們通常是經過密度和屏幕大小來匹配。
  5. dip---boss的傷害公式,boss的傷害實際上是一個數字,但這個數字是有公式轉換的,例如法系攻擊,物理攻擊的都是有一個公式轉換後在附加到咱們身上。固然請不要糾結你的防護,抗性之類的,dip就是一種轉換公式,讓不一樣的boss都能統一轉換成正確的傷害。

4.1.2多屏幕支持的範圍

Android1.6開始就支持多屏幕和密度了,這都是爲了更好的用戶體驗,爲了簡化咱們多屏幕的開發。android提供了一組範圍讓咱們使用:

關於屏幕大小: small, normal, large, xlarge(看來目前遊戲boss的體型就這四種)

注意: android3.2會有些不一樣,之後咱們在講平板和手機支持時會說明

屏幕密度: ldpi (low), mdpi (medium), hdpi (high), xhdpi (extra high) (boss的模型細粒度目前也就四種了)。這些廣義的大小和密度都是基於normal大小和mdpi來當作標準的。通常來講咱們分辨率爲800*480或者854*480的手機密度都是240(hdpi),屏幕大小都爲large。

每個大小和密度都有一個跨越幅度。但這些幅度中具體的微調咱們是不用關心的,android會幫咱們處理,下面咱們來看圖 4-1:

 

 圖4-1 實際大小和實際密度的取值範圍(這是個近似值)

 

咱們設計UI都會要考慮一個最小化的空間,android中都是使用dp(dip)單位的。如下是官方參考

xlarge 屏幕至少960dp x 720dp

large 屏幕至少 640dp x 480dp

normal 屏幕至少 470dp x 320dp

small 屏幕至少 426dp x 320dp

屏幕大小和密度是能夠獨立的,不是說一個5寸屏的密度就必定是hdpi。有一個很重要的例子就是例如一個WVGA (800×480)屏幕可能在不一樣的設備上會有mdpi和hdpid兩種密度。也就是說一樣體型的boss,有的模型很粗糙,有的很細膩。

 

4.1.3獨立密度

獨立密度是很重要的,由於沒有它,一個UI元素(好比一個按鈕)會出如今一個物理屏幕很大,但密度不多的顯示效果(看起來就是像是被強行放大的,失真很嚴重)。這樣相對位置的改變會出問題,下面咱們來看圖:

 

 圖4-2 你的應用沒有支持不一樣密度產生的效果

 

圖4-3你的應用具備良好的支持而產生的效果

android 系統幫助你的應用實現獨立密度的方法有兩種:

1.系統縮放dp單位來適用當前屏幕密度

2.系統基於當前屏幕密度縮放drawable資源到適用的大小

圖 4-2是用像素單位來定義的大小。你發現他們的佈局徹底變了,有的大有的小。這是由於他們的實際屏幕大小多是同樣的,高密度屏幕每英寸的像素更多(因此你會發現像素同樣,但高密度的設備顯示出來的效果卻很小)。圖4-2使用的是dp單位,基於mdpi密度的設備它不會變化,ldpi它會自動縮小,hdpi它會自動放大。因此效果很是好。圖片顯示出來的樣子和大小徹底同樣。

使用密度系統會縮放圖片使之看上去徹底同樣,但細心的你會發現有些圖片變模糊了。因此咱們應該提供可選擇的圖片資源讓系統來自動選擇圖片以適應不一樣的密度。因此用Eclipse自動生成的工程項目中的hdpi,mdpi,ldpi三個文件夾就是用在這裏的。這樣就不會有模糊的感受了。固然對於矢量圖來講放大的失真也沒什麼影響,這裏能夠理解爲只針對位圖。

4.2怎樣支持多屏幕

以上咱們學習了這麼多的理論基礎。如今咱們應該優雅的處理它們了。

1. 明確的在manifest文件中指出你的應用支持的屏幕大小。

咱們能夠有選擇性的過濾掉一些老掉牙的設備,以減輕咱們的工做量。但這並非一個好的方法僅供參考。在manifest 中使用節點<supports-screens>

2. 根據不一樣的屏幕大小提供不一樣的佈局

默認的android會調整你應用的佈局來適應當前設備的屏幕。大多數狀況下能夠知足,但某些特殊狀況,你的UI可能須要一個更精確的調整。例如,一個larger 屏幕,你可能想要利用額外的屏幕空間調整位置和一些元素的大小,或者一個小屏幕中,你可能須要調整到恰好合適。好比你須要適應一個extra large 屏幕。你能夠在文件夾layout-xlarge/下放置佈局(讀者請記住通常layut下放的都是xml佈局文件)。

Android 3.2開始,有一種新的方式。例如你的平板需求至少600dp的屏幕寬度,你可使用layout-sw600dp 這種文件夾放置你的佈局文件。之後咱們在平板一節會詳細描述。

3. 根據不一樣的屏幕密度提供不一樣的位圖

默認android會縮放你的位圖(.png.jpg.gif),另外還有一種專用的Nine-Patch(.9.png)。例如,你的應用提供的位圖僅僅爲標準密度(mdpi),那麼在hdpi的屏幕上這些位置會被等比放大。因此咱們應該有選擇性的對於不一樣的屏幕密度包含不一樣的分辨率。

因此android針對圖片資源配置後綴,前面咱們知道的4種密度(ldpi,mdpi,hdpi,xhpi),若是用於高密度的屏幕,咱們應該使用drawable- hdpi/這種文件夾。以上關於屏幕大小和密度的後綴都符合屏幕支持的那些範圍。

在運行時, 對於給定的資源系統會使用如下這些步驟來顯示:

1. 系統會使用合適的替代資源

基於當前屏幕的大小和密度,系統會針對屏幕的密度和大小使用資源。例如,若是設備有一個 hdpi的屏幕那麼當App請求一個drawable 資源時,系統會在最匹配的的設備配置下的drawable 資源目錄尋找。能夠取決於其餘可替代的資源,使用drawable-hdpi/的資源目錄最匹配的,因此係統會使用drawable-hdpi目錄下的資源。

2. 若是沒有可用的匹配資源,系統會使用默認資源等比放大或縮小以匹配當前屏幕的大小和密度。

這裏的默認資源是沒有後綴的。例如,「drawable」就是默認的drawable/ 資源。系統會認爲默認的資源都是基於normal 屏幕大小和medium 密度設計的。系統會等比縮放默認的密度資源來匹配hdpi密度或者ldpi密度。當系統沒有找到針對密度資源的目錄時,它就一直會使用默認的資源。例如,若是系統想找一個ldpi(低密度)的資源,但找不到。那麼系統會等比縮小hdpi的資源,爲何不尋找mdpi呢?由於系統對於hdpi更容易縮放,它的係數爲0.5,相比mdpi的0.75來講。0.5的的性價比更高(方便計算,正確率也高一點)。關於這一點最好的證實就是android版本的QQ瀏覽器。你解壓後發現它關於drawable就只有drawable和drawable-hdpi兩個文件夾,看來騰訊裏android的開發者應該很熟悉android系統規律了,由於默認的drawable 就是mdpi,只須要定義一套hdpi的drawable資源就好了。

4.2.1使用配置後綴

Android支持幾種配置後綴,它容許你控制系統有選擇性的篩選基於當前屏幕設備的資源文件。一個配置後綴就是一個String你能夠在資源目錄文件夾下追加指定的後綴便可。使用一個配置後綴的方法步驟:

1.在你的工程res/目錄下建立一個新的目錄,格式爲<資源名>-<後綴>: 

<資源名>是標準的資源名字(例如 drawable或者layout)

<後綴> 是指定屏幕配置使用哪種資源(例如hdpi或者xlarge)

咱們可使用的後綴不只僅只有一個哦,在一個文件夾下咱們能夠同時使用多種後綴來限定資源,使用"-"便可。

2.在新的目錄中保存合適資源,資源文件的命名必須和默認資源文件同樣。

例如 xlarge是一個後綴用於extra large 屏幕。當你追加後綴時(例如layout-xlarge) ,它說明系統會在extra large屏幕上使用這些資源

屏幕特徵

後綴

描述

大小

small

資源用於small大小的屏幕.

normal

資源用於normal 大小的屏幕。(這是默認的基準大小)

large

資源用於large 大小的屏幕

xlarge

資源用於extra large 大小的屏幕

密度

ldpi

資源用於 low-density (ldpi) 密度的屏幕 (~120dpi).

mdpi

資源用於medium-density (mdpi) 密度的屏幕 (~160dpi).

(這是默認的基準密度.)

hdpi

資源用於high-density (hdpi) 密度的屏幕 (~240dpi).

xhdpi

資源用於extra high-density (xhdpi) 密度的屏幕 (~320dpi).

nodpi

資源用於全部密度. 系統不會根據當前屏幕密度去縮放資源

tvdpi

資源用於mdpi 和hdpi二者之間的某的密度;大約是213dpi。

這個不多用到。它主要用於電視,大多數App不須要用到它。

若是你須要tvdpi資源,它的大小大概是1.33*mdpi(160)例如,

一個在mdpi下100px*100px的圖片,那麼在 tvdpi中它會

變成133px*133px。的圖片,那麼在 tvdpi中它會變成133px*133px。

方向

land

資源用於橫屏

port

資源用於豎屏

長寬比

long

資源用於長寬比相差很遠的配置(相對於4寸(normal)屏幕左右基準屏幕)

notlong

資源用於長寬比差很少的配置(相對論,同上)

表格4-1 後綴配置表

注意: 若是對於android3.2或者更高的版本,有一些新的後綴,等下咱們會講解

下面咱們就來舉一些詳細的例子:

res/layout/my_layout.xml             // 用於normal 屏幕大小的佈局 ("默認")
res/layout-small/my_layout.xml       // 用於small 屏幕大小的佈局
res/layout-large/my_layout.xml       // 用於large屏幕大小的佈局
res/layout-xlarge/my_layout.xml      // 用於extra large屏幕大小的佈局
res/layout-xlarge-land/my_layout.xml // 於extra large屏幕大小而且是橫屏的佈局

res/drawable-mdpi/my_icon.png        // 用於中等密度的位圖
res/drawable-hdpi/my_icon.png        // 用於高密度的位圖
res/drawable-xhdpi/my_icon.png       // 用於超高密度的位圖

當android系統在運行時選擇資源時,當你沒有加後綴時它本身有必定的邏輯判斷來匹配最適合的資源。當基於使用大小的後綴時,若是當前沒有資源更好的匹配你的後綴,那麼系統會使用比當前屏幕更小的資源來計算(例如,若是你沒有添加large後綴,那麼一個large大小的屏幕將會使用在normal(默認的)大小的屏幕資源來放大後顯示),若是可用的資源後綴比當前屏幕更大(其實仍是沒匹配上),那麼系統將不使用它們(例如你吧全部layout資源放入xlarge後綴中,但設備是一個normal屏幕,系統就不會使用這些資源)。

是否是有點頭暈了,簡要的概述下就是若是沒有匹配的系統會使用默認的資源,若是連默認下都沒有放資源而且沒有匹配到你的後綴,那麼系統就沒有資源可用啦。

注意:某些狀況下你可能須要用到nodpi後綴,由於你可能不想要它被縮放,或者你想要在運行時經過代碼手動縮放它。 

4.2.2設計可供選擇的Layouts和drawables

咱們應該根據於本身應用程序的需求來建立可供選擇的資源類型。一般,你應該使用大小和方向後綴來提供可選擇的Layout資源,使用密度後綴來提供可選擇的位圖drawable資源

可供選擇的layouts

你應該知道你的應用是否有這個需求,是否須要根據不一樣的屏幕來提供可選擇的佈局。例如:

1.當在一個small屏幕上測試時,你發現你的佈局沒有徹底符合你的要求或者是沒有匹配好屏幕。例如一排按鈕沒有很好的在small屏幕上顯示。這種狀況你應該爲small屏幕提供一個可供選擇的佈局用來調整按鈕的大小或者位置。

2.當在一個extra large屏幕測試時, 若是沒有有效利用大屏幕或者明顯的被拉伸了,這種狀況你也應該提供一種根據extra large屏幕的佈局,而且最好再優化它以適應未來的平板設備

雖然你的App沒有提供大屏幕的佈局運行起來也沒問題,但UI被明顯拉伸的感受會讓用戶以爲這個應用不太精緻,用戶體驗會大打折扣

3.當在橫屏和豎屏對比測試時, 你應該注意到UI元素在豎屏下是在底部,橫屏下倒是右邊。若是你一直須要都在底部的話,你也應該配置後綴

總的來講,你應該確保你的應用佈局以下:

(1)適用於小屏幕

(2)優化應用程序使之在大屏幕上利用額外的空間

(3)優化橫豎屏

若是你的UI使用位圖,那麼你應該使用nine-patch 位圖文件。nine-patch 這是android提供的一種格式而且它還提供一種根據讓你吧美工出的圖片稍微修飾。這種格式能容許你設置能夠縮放的2D範圍。當系統須要縮放時,系統會在你指定區域縮放 Nine-Patch位圖。這樣在不一樣的屏幕大小下你就不須要提供不一樣的位圖資源了(能夠節省APK的大小)。由於Nine-Patch會自動調整它的。但在不一樣的屏幕密度下你應該仍是提供可供選擇的Nine-Patch 文件。這樣你的應用纔會更健壯。關於nine-patch的使用咱們之後會在第二大篇的圖形章詳細講述。

可供選擇的drawables

幾乎每個應用都會根據不一樣的密度提供可選擇的drawable資源,由於這對於用戶體驗和UI真的很重要。下面咱們來看一下圖4-4的密度轉換圖

 

圖4-4 根據每個密度下drawable下位圖的相對大小(目前4種技能應該夠用了)

注意: 根據密度你僅須要提供drawable下的位圖文件,若是你使用Xml來定義shape,colors或者其餘drawable的資源,你就應該放到"drawable/"默認目錄下

根據不一樣的密度提供可選擇的位圖drawable資源時,你應該在四種密度下使用3:4:6:8的縮放比。讀者能夠參考工程下每一個不一樣的drawable裏的icon尺寸:

36x36 ldpi

48x48 mdpi

72x72 hdpi

96x96 xhdpi

 

4.3關於Android3.2平板上的佈局

第一代平板運行於android3.0上,通常是使用xlarge配置後綴(res/layout-xlarge/)來聲明平板佈局。爲了提供其餘類型的平板和屏幕大小----尤爲是7寸平板!android3.2引入了一種新的方法來爲更多離散的屏幕大小來指定資源。你的佈局須要一種新的基於控件容量的技術(例如指定600dp的寬度),而不是試圖使你的佈局去適應那些android歸納性的分組(例如large或xlarge)

當android去歸納大小分組時,對於7寸平板他們也很棘手,由於5寸手機和7寸平板使用一樣的large組。這兩個設備在size上表面上看起來更貼近彼此,但其實UI在至關大程度上仍是不一樣的,用戶體驗的效果也不太好。所以一個7寸和5寸的屏幕將不使用一樣的layout。根據這兩種屏幕你應該儘量的提供不一樣的佈局,android如今容許咱們指定基於寬度或高度layout資源,記住請使用dp單位。

例如, 在你根據平板風格設計佈局之後,你可能須要當屏幕小於600dp的寬度時候中止工做。這個界限會由於你的平板佈局而變成最小的尺寸。這樣你能馬上指定當至少寬度在600dp時候,layout中的資源文件才被用到。

注意: 記住!dip是一個很是重要的單位,你的佈局大小也應該用dp單位。由於它能夠看作一種比例單位而非像素那樣的絕對單位。

4.3.1使用新的大小後綴(非密度)

你能爲你的佈局指定不一樣的資源配置。在下方的表格2中這些新的後綴提供給你更多的控制,相對於傳統的(small, normal, large, and xlarge)這些已經超過它們了

注意: 你指定使用的這些後綴並不是實際的屏幕大小。固然,這些大小是根據寬度(dp單位)和高度(dp單位)被用於activity的window中。window的特殊性在於它方法是有個動做條,用來顯示電池和通知信息的。因此你在設計UI的時候須要考慮 你的應用是否須要顯示動做條。下面咱們看下面表格4-2:

屏幕 配置

後綴值

描述

最小寬度

sw<N>dp

例如:
sw600dp
sw720dp

用這個後綴能夠確保無論當前屏幕是否橫豎屏。你的應用有一個至少<N>dp的可用寬度 

例如, 若是你的layout一直需求最小屏幕的一邊爲600dp,那麼你能使用這個後綴建立layout資源(res/layout-sw600dp/)。對於用戶來說,無論600dp是寬仍是高,僅當屏幕可用的最小尺寸至少是600dp時,系統會使用這些資源(就是說你的設備不用以什麼角度看,長和寬的某一邊的最小值大於或等於600dp時,系統就會使用)。當屏幕水平方向改變時,設備的最小寬度不會改變

設備的最小寬度要考慮屏幕的裝飾和系統UI。例如,若是設備有一些持續不變的沿着你最小寬度的軸方向的UI元素(動做條等),那麼系統會宣佈最小寬度比實際屏幕寬度要小,由於那些UI元素對於你的UI來講是不可用的

 由於寬度是常常影響佈局的一個重要因素,因此使用最小寬度來控制通常的屏幕大小(針對平板)仍是有用的。 可用寬度也是決定是否使用單屏幕布局(手機)和多屏幕布局(平板)關鍵因素,所以你極可能關心每個設備上的最小方面。

屏幕可用寬度

w<N>dp

例如:
w720dp
w1024dp

用dp單位指定一個最小化的在可用寬度下可使用的資源。系統會根據寬度改變(橫豎屏切換時)來匹配這個值,並反映到當前實際可用的寬度上

當你決定是否使用多屏幕布局時它頗有用,由於即便在平板設備上,你也常常不想要多屏幕布局會根據橫豎屏來變化。所以你能夠用這個來指定最小化的寬度需求,它能夠用來代替方向後綴(land,port)和大小後綴(small,normal,large,xlarge)使之整合到一塊兒。

屏幕可用高度

h<N>dp

例如:
h720dp
h1024dp
etc.

用dp單位指定一個最小化的屏幕高度。和"屏幕可用寬度"相似

表格4-2 android3.2加入的新後綴(注意是基於屏幕大小的而不是密度)

當使用這些後綴時你可能以爲比傳統的那四種後綴複雜些,實際上你用事後就發現它很簡單,它能一次簡化你的UI需求。當你設計UI時,主要的事情就是須要考慮咱們App中的實際大小,而且對於手機和平板風格的切換。它取決於你某些特定切換點的設計,可能對於平板佈局你須要720dp的寬度,可能600dp就足夠了,或者480,或者這兩個之間。使用表格2的後綴,你能夠在佈局改變時精確的控制大小。之後咱們會根據實際開發來說述的

4.3.2關於實際配置的例子(非密度)

如下是一些屏幕數據:

320dp: 一種手機屏幕(240x320 ldpi, 320x480 mdpi, 480x800 hdpi, 等).

480dp: 一種平板 (480x800 mdpi).

600dp:  7寸平板(600x1024 mdpi).

720dp: 10寸平板(720x1280 mdpi, 800x1280 mdpi, 等).

咱們使用表格2中的後綴來爲咱們的應用定義不一樣的切換風格(包括手機和平板),例如, 若是咱們的平板佈局600dp是最小可用寬度,咱們能提供兩套佈局方式:

res/layout/main_activity.xml           # 手機
res/layout-sw600dp/main_activity.xml   # 平板

這種狀況下,屏幕可用的最小寬度爲600dp,這是僞了支持平板佈局被應用。

或者你可能想要區分7寸和10寸平板,你能夠這麼作:

res/layout/main_activity.xml           # 手機(比600dp更小的可用寬度)
res/layout-sw600dp/main_activity.xml   # 7寸平板 (600dp的寬度或者更大)
res/layout-sw720dp/main_activity.xml   # 10寸平板(720dp的寬度或者更大)

注意上面的兩套例子的使用使用 sw(最小寬度)後綴,它指定屏幕的兩邊中的最小一邊,無論屏幕的水平方向。它忽視橫豎屏。

然而某些狀況下咱們須要精確佈局。例如若是你有一個 2個面板合併在一塊兒的顯示效果。是否屏幕提供至少600dp的寬度,是否橫豎屏你都要使用它。就應該這:

res/layout/main_activity.xml         # 手機(小於600dp的可用寬度)
res/layout-w600dp/main_activity.xml  #多面板 (任意一個面板都是600dp或者更高的寬度)

注意上面這裏用的是w<n>dp。實際設備可能須要兩套佈局,它依賴於屏幕的水平方向(一邊至少是600dp的寬度,另外一邊小於600dp,你會發現無論橫豎屏都知足這個條件。因此你須要準備兩套關於橫豎屏的佈局)

關於什麼是多屏手機或者叫多面板手機。我發個圖給你們看看就明白了(下面這個手機其實有3屏),如圖4-5所示:

 

圖4-5 三屏手機截圖

4.4實踐中應該注意哪些

在多樣的屏幕中咱們使用傳統的四種配置仍是能很好的得到支持的。上面咱們提供了多種定義的方法。添加這些後綴能確保你的App能適應不一樣的屏幕設備。下面是一些方法,告訴你如何確保你的應用程序能夠正確地顯示在不一樣的屏幕上:

1.在XML佈局文件中請使用wrap_content, fill_parent, 或者 dp 單位

2.在你的程序代碼中最好不要使用像素(px)這種硬編碼

3.不要使用AbsoluteLayout (絕對佈局)

4.提供不一樣的位圖drawable資源來適應不一樣的屏幕密度.

1. 使用在XML佈局文件中請使用wrap_content, fill_parent, 或者 dp 單位

當在XML中爲你的Views定義android:layout_width和android:layout_width時,使用"wrap_content","fill_parent"或者dp單位來保證View在當前屏幕上得到一個合適的大小。

例如,一個view的寬爲layout_width="100dp"   在mdpi的屏幕下它是100px,在hdpi的屏幕下它就是150px,但顯示出來的效果在物理屏幕上是同樣的大小

一樣, 對於定義文本的大小,咱們應該用sp(scale-independent pixel)。 由於sp和dp的概念是同樣的,它們不是絕對的像素值

2.在你的程序代碼中最好不要使用像素(px)這種硬編碼

因爲執行緣由並使代碼更簡單,android系統使用像素做爲標準單位用來描述尺寸或座標值。就是說在代碼中android仍是使用的像素用來表述尺寸,但它是基於當前屏幕密度的,因此是變化的。若是代碼中 View.getWidth()返回的值是10,這麼這個10的單位爲像素,但這僅僅是在某一個密度的屏幕上而已,其餘不一樣密度的屏幕上它的結果就會不同了。因此android是不建議咱們在代碼中用像素來設置佈局的,由於它會加劇咱們的工做量,而且處理的也不必定很好。想象一下這麼多屏幕設備你若是用代碼來適配的話,你就得考慮的很是嚴謹了。不過若是你只針對某一種屏幕的話就另當別論了,但這種狀況不多見。

3.不要使用AbsoluteLayout (絕對佈局)

請不要使用AbsoluteLayout(絕對佈局)這種佈局是早期android的版本,在android1.5版本的時候就已經廢棄了。雖然爲了兼容之前很老的設備這種佈局還存在,但目前來講,咱們已經徹底沒有必要再使用它了。 

4.提供不一樣的位圖drawable資源來適應不一樣的屏幕密度

雖然在當前屏幕配置上系統會自動縮放你的layout和drawable資源,但爲了優化某些特定密度的設備,可能咱們並不想讓它縮放,咱們想給這種密度指定一套資源也是能夠並且這樣的效果也很不錯,能更好的根據不一樣的屏幕來調整咱們的UI。這個咱們在本文中已經反覆提到了,目的就是爲了加深你的印象。

一個很好的例子就是關於你用eclipse生成android工程的時候,三種不一樣的drawable(res/drawable-ldpi/icon.png,res/drawable-mdpi/icon.png,res/drawable-hdpi/icon.png)中都

會自動生成不一樣尺寸的icon.png。

注意: 若是咱們沒有定義某個後綴,但屏幕密度又是須要那個後綴的話,那麼系統會假定你的資源都是基於mdpi(默認)的。並會放縮你的資源

4.5 關於密度額外的注意事項

這一段主要描述android在不一樣屏幕密度上是怎麼縮放位圖drawable的,咱們須要更進一步的掌握系統控制位圖資源的原理。當在運行時操做圖形,咱們能更好的理解它是怎樣支持多屏幕的,咱們應該瞭解下系統是如何保證適應屏幕並適當的縮放位圖的:

1.載入時自動縮放 (好比位圖drawables)。

基於當前屏幕的密度,系統使用任意大小或者密度的資源來顯示它們的時候是沒有縮放過的。若是在當前密度下沒有可用的資源,那麼系統會載入默認資源並等比縮放它們來匹配當前屏幕的密度。除非有有針對密度的後綴出現,否則系統都是認爲默認資源(沒有後綴的drawable)是爲mdpi的密度來設計的。所以系統這個時候會調整位圖的大小來適應屏幕。

若是你需求資源縮放以前的大小,那系統實際上返回的是縮放後的大小。例如:若是你沒有指定hdpi後綴,一個在mdpi下50px*50px的位圖在一個hdpi下會縮放爲75px*75px。在hdpi屏幕下系統會返回這個75px這個大小。若是你不但願系統根據不一樣的密度來縮放資源,那麼請記住使用「res/drawable-nodpi/」

2.運行時自動縮放(好比像素的大小和座標)

一個應用能關閉載入時自動縮放的這個功能,只要你在manifest中設置android:anyDensity ="false",或者在程序中使用BitmapFactory.Options.inScaled返回的值爲false。在這種狀況下。系統會在繪製的時候自動等比縮聽任何絕對座標和像素大小。這麼作確保用針對像素的屏幕元素能一直顯示。系統會處理縮放,而後轉化並報告縮放的像素大小,而不是物理像素大小。下面咱們來舉個例子:例如,假設一個設備有一個WVGA(800*480)下是hdpi的屏幕,而且它和在傳統的HVGA(480*320)屏幕同樣的物理大小,但執行應用的時候關閉了載入時自動縮放這個功能。這樣的話,當系統查詢屏幕大小時,它會報告一個320*533的大小,爲何會是320*533呢,咱們開的模擬器是800*480的啊!!由於系統在繪製的時候縮放了。系統報告的是縮放後的像素大小,而不是咱們模擬器上的物理大小。而後App須要繪製操做時,原本想在(10,10)上的位置繪製,但會變成(15,15)。若是你的應用直接操做縮放位圖,那這種差別可能致使意外的行爲。之前不少剛開始接觸android的朋友常常會遇到系統報告320*533的這種問題。緣由就是因爲咱們關閉了載入時自動縮放這個功能。你關閉了它的話,它就會在運行時縮放並返回結果。因此咱們要檢查manifest中是否設置android:anyDensity ="false"。若是有趕快去掉。也許還有朋友發現沒有設置怎麼也會出現這種問題,這是因爲之前比較老的SDK版本系統默認設置關閉了載入時自動縮放這個功能致使的,不過目前這種狀況不多發生了。 

4.5.1運行時建立縮放的位圖對象

咱們的應用若是須要在內存中建立一個位圖(bitmap)對象,那麼系統會認爲你是基於mdpi密度的屏幕來建立的。默認的,系統會根據屏幕密度在繪製的時候自動縮放這個位圖。當位圖沒有指定密度屬性時候,系統會自動縮放。爲了控制位圖在運行時建立後是否被縮放,咱們能夠指定位圖的密度屬性,使用Bitmap.setDensity()。具體的值能夠傳DisplayMetrics.DENSITY_HIGH或其餘。咱們還能夠從文件或者一個流中使用BitmapFactory來建立位圖,使用BitmapFactory.Options來定義位圖的屬性,那麼系統會根據你的屬性來縮放它。咱們還可使用BitmapFactory.Options.inDensity來指定這個位圖是否須要匹配當前的屏幕密度。若是咱們設置BitmapFactory.Options.inDensity=false;那麼系統在載入位圖時將不會自動縮放它,只會在運行時縮放它。使用運行時縮放CPU佔用率高,內存佔用低。使用載入時縮放CPU佔用率低,內存佔用高。如何取捨就看你的需求了。

4.5.2 dp和像素的轉換

有些狀況下,dp和px只須要相互轉換的。例如一個應用在用手指滑動屏幕的時候會感應用戶的手指移動了多少個像素。在一個normal和mdpi的屏幕下,用戶必須移動16px/160dpi,等價於十分之一英寸(大約2.5mm(毫米))。那麼在一個hdpi(240dpi)的屏幕上用戶必須移動16px/20dpi,等價十五分之一英寸(1.7mm)。距離是很短的,所以這對用來講會很敏感。爲了修復這個問題,須要用代碼吧dp轉換成px單位。例如:

 

// 手勢的響應的範圍(dp)

privatestaticfinalfloat GESTURE_THRESHOLD_DP =16.0f// 獲取屏幕的密度來縮放

finalfloat scale =getResources().getDisplayMetrics().density;

//根據密度吧dp轉換成px

mGestureThreshold =(int)(GESTURE_THRESHOLD_DP * scale +0.5f);

// 可使用這個響應的範圍了

 

 

這裏DisplayMetrics.density的值爲(0.75[ldpi],1[mdpi],1.5[hdpi],2[xhdpi]) ,其實咱們還可使用ViewConfiguration類來處理,但前提是打開了載入時縮放這個功能(目前來講,默認都

是開的不用擔憂)而且咱們可使用ViewConfiguration.getScaledTouchSlop()來直接得到換算距離。具體使用以下:

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

 

4.6 如何在多種屏幕下測試咱們的應用

首先咱們來看一下圖4-6,這是使用AVD工具設置虛擬設備的截圖

 

圖4-6 這是android SDK中的AVD工具,它提供一套虛擬機設備。(最後1,2章會詳細講述使用方法)

在發佈咱們的應用以前,我應該在不一樣的屏幕大小和密度上測試咱們的App。android SDK中有不少模擬器,咱們能夠修改模擬器上的默認的大小,密度,分辨率來整合測試。例如使用android2.1版本的模擬器,咱們能夠同時新建多個2.1的版本,但每一個的密度不一樣。這麼多模擬器能夠爲咱們省下不少錢來買不一樣的手機。若是你想修改某個模擬器的密度,你只須要選中它點擊右邊的edit就能夠修改了。以下圖4-7所示:(這裏只須要留點印象後面會有章節單獨的講述AVD參數配置)

 

圖4-7 在AVD中點擊edit後的截圖

爲了測試應用是否支持多種不一樣的屏幕,咱們應該建立一系列的AVD(android virtual devices)。若是不用eclipse的話,咱們能夠在sdk目錄下執行SDK Manager.exe這樣就顯示出圖4-6的界面。

4.7 本章小節

關於android的屏幕和分辨率,這是很是重要的一個知識點,但願你們認真學好它,在之後的開發過程當中絕對是很是有幫助。如今咱們稍微回顧一下關鍵的內容:

一,Boss的5個關鍵點

1.boss的體型(屏幕大小)

2.boss的模型細粒度(屏幕密度)

3.咱們看boss的角度(屏幕的方向)

4.boss的整體外觀和風格(屏幕的分辨率)

5.boss的傷害公式(dp單位)

二,咱們也有相應的對策對付他們

drawable(咱們遊戲角色的技能,目前4種(ldpi,mdpi,hdpi,xhdpi))

layout(咱們遊戲角色的裝備,目前4種(small,normal,large,extra large))

三,怎麼樣搞定這些boss

manifest文件中指出你的App支持的屏幕大小

根據不一樣的屏幕大小提供不一樣的佈局

根據不一樣的屏幕密度提供不一樣的位圖

四,最後咱們須要熟悉後綴和一些公式(就像遊戲boss的攻略)

目前那麼多後綴不須要徹底記住(之後用的多天然就記住了),但須要有個印象(後綴能夠爲drawable服務,也能夠爲layout服務,你能夠想象成後綴是一種附魔提高裝備(layout)的屬性,又是一種銘文用來提升技能(drawable)傷害或效果)

還記得3:4:6:8嗎? 還記得 0.75x, x ,1.5x, 2x嗎?這些都很重要哦

本文來自jy02432443,QQ78117253。轉載請保留出處,並保留追究法律責任的權利

相關文章
相關標籤/搜索