Sunday, March 11, 2012

談談Android的螢幕解析度

撰寫時間︰2012/03/12 13:15
更新時間︰2012/03/23 11:54
文章更新次數︰3

一、前言
Android手機有多種解析度,
視覺或美工在設計版面時,
倒底該怎麼做,
才能讓每種不同規格的Android手機,
表現出其最大效能?

二、文章開始
讓我們先從Android的圖形資源檔說起。

左邊這張圖是Android置放圖片的資料夾,
如果以手機來說,
至少可以分成4種資料夾,
分別為drawable、drawable-hdpi、drawable-mdpi和drawable-ldpi。


因為這樣的資料夾分類,
讓每種解析度的手機,
能聰明的依照它們自己的螢幕密度(density),
找到他們需要的圖檔應該要在哪個目錄取得
關於這4個資料夾的使用方式,
以及該放什麼圖片進去,
我會在稍後提及。

註︰

需要先在AndroidMenifest.xml裡將Any density設為true,
手機才會依自己的螢幕密度(density)去找適當的drawable資料夾,
否則會一律從drawable這個預設目錄去取得圖形資源。
(如果又沒有設drawable資料夾,
則會從其它的圖形資料夾下找到該圖形資源,
然後依照density的比例去自動縮放。

如果你現在看不懂我說的,
無妨。
因為等一下我還會再說明。)

Android官方技術文件中提供目前Android的解度析有以上這些規格(但實際上有更多)
要如何理解這張表格,
小鰻當時也花了很久的時間在摸索,
當然,要怎麼知道手機的density,
Google很多人都有教了,
不在此特做說明。

以欄位來看,
第1欄屬於ldpi的手機規格至少有︰
QVGA(240x320)、WQVGA400、WQVGA432、WVGA800、WVGA854...。

 Android Design Guide建議我們在處理每種解析度的圖片問題時,
可以使用底下2種方式︰
1.先從mdpi的規格去製圖,然後再使用photoshop之類的圖片編修軟體,向上調整尺寸和向下調整。
2.從最大尺寸去製圖(假設你想開發手機App,可以從Galaxy Nexus的density320開始繪製),然後再向下縮小。

Android的最基本尺寸規格是Medium Density(160) - mdpi
任何其它的Android尺寸,
都是由mdpi去向上或向下延伸換算出來的,
因此我個人是比較推薦使用第1種 - 從mdpi去調整圖形大小的方法來製圖。

photoshop是Google很推薦的繪製工具,
因為使用這套軟體,
可以自由的拉大和縮小圖形也不會失真(以專案檔的方式來說的話)。

如同我前面所說,
如果要設計手機版面,
至少會有4種drawable資料夾,
這裡解釋一下這4個資料夾的用法。

1.drawable
drawable資料夾相當於drawable - nodpi,
如果手機從這個資料夾抓出圖片,
那麼系統繪製圖片的方式,
是"圖片有多大就畫多大",
以1:1的方式去繪製。

所以,如果使用這個資料夾,
通常還要在程式裡做很多螢幕解析度的換算,
不然會遇到圖片在小手機,
根本完全跑版、超出手機螢幕大小的問題。

2.drawable - mdpi
mdpi(density160)是Android標準的規格尺寸,
任何其它dpi,都是從mdpi去演算及延伸的,
強列建議先由mdpi去排版製圖,
然後再去調整其它的解析度。

3.drawable - hdpi
前面說到,
Android的標準尺寸是mdpi(density160),
而hdpi則是density240,
240(hdpi density) /160(mdpi density) = 1.5。
這樣的比例換算下來,
螢幕顆粒密度比原本的mdpi還要精密,
因此,
你會發現圖片在mdpi中看是正常大小,
但到hdpi的手機來看,
圖片被明顯縮小了。

因此,
這個資料夾裡的圖片,
你必須畫得比drawable - mdpi的圖檔還大。
大幾倍?
答案是...150%

這個值就是剛才240/160=1.5算出來的值,
你必須將mdpi的那張圖,
用photoshop放大150%另存新檔,
放在drawable - hdpi來用,
才能顯示跟drawable - mdpi一樣的畫面大小。

3.drawable - ldpi
ldpi的Density為120,
120/160 = 0.75,
因此,
使用photoshop將剛才mdpi的尺寸,
縮小成75%
放進drawable - ldpi目錄,
將能讓呈現出來的畫面,
跟mdpi的畫面一樣。

如果要製作不同解析度的icon,你需要對每一種dpi去客製化,才能在每種手機上呈現一樣的結果。


如果你問我︰
「天啊!
我一定要花那麼多的工夫在製做不同尺寸的解析度嗎?」
這個答案是可選擇的。

why?
如果你今天開發的App,
畫面只繪製mdpi,
那有沒有辦法在ldpi和hdpi正常顯示呢?
答案是...可以。

把drawable目錄刪掉,
剩下其它3個目錄(drawable - ldpi、drawable - mdpi、drawable - hdpi),
且將繪好的mdpi圖形,
丟進drawable - mdpi,
如果程式發現現在使用的手機,
是ldpi或hdpi時,
系統會自動去換算放大或縮小,
也不會讓原本設計給mdpi的圖片尺寸,
在hdpi或ldpi中跑版。
但...這就牽扯到視覺(美工)人員最在意的品質問題。

品質是視覺(美工)人員的生命,
他們的職責就是替產出的作品負責,
畫面上的每1 mm,
都是比自己的小孩還要親的小孩。
當然,
也是有視覺(美工)人員是比較...隨遇而安的心態啦...。

讓系統去自動縮放圖片大小
壞處有下︰

1.如果手機解析度比mdpi還大(如hdpi),
那麼這張圖將被拉大,
畫面將沒那麼精美了。

 2.如果手機解析度比mdpi還小(如ldpi),
那麼這張圖將被縮小,
看起來似乎沒什麼問題,
但你要知道,
使用者手上拿的這種ldpi手機,
通常都是效能極差的Android手機(我們稱它為Android低階機,講好聽叫入門機),
以台灣來說,
通常都是電信業者綁門號,
 0元就能帶回家的Android手機。

這種品質的手機,
你在開發時,
會發現它的所有硬體支援度都比中高階的Android手機還差。
如果iPhone開發工程師已經在開發下一款產品時,
老闆為了要旗下的產品支援所有Android手機,
你會發現你還在調校這些低階手機。

現在,
你把mdpi大小的圖片塞進這隻效能極差的ldpi手機中,
因為效能極差,
沒多久,
你就會遇到記憶體不足(我前面的文章有提到)的問題!

三、結論
無論你是視覺(美工)人員或者是Android程式設計師,
不管是螢幕畫面還是手機效能,
最好都還是替不同的螢幕解析度去客製化不同的圖片大小,
一來控制畫面品質,
二來也能確保程式穩定度。

這些細心,
每一種規格的Android手機使用者都能依各自的可用資源看到你呈現出來的產品,
何樂而不為?

四、備註
我開發過的手機和平板規格︰
1.Nexus one(800x480, density 240)
2.Nexus S(800x480, density 240)
3.Galaxy Nexus(1280x720, density 320)
4.HTC Hero(480x320, density 160)
5.Sony Arc(854x480, density 240)
6.遠傳小精靈(320x240, density 120)
7.HTC野火機1代(320x240, density 120)
8.Samsung SII(800x480, density 240)
9.HTC Flyer平板(1024x600, density 160)
10.Samsung Tab 7.7(1024x600, density 170)
11.HTC Desire(800x480, density 240)
12.HTC Incredible(800x480, density 240)
13.HTc Sensation(960x540, density....)
還有更多...

以上如果規格或Density有錯,
煩請告知。
感謝

其它導讀︰
1.處理多螢幕解析度問題-PartII(外文)

10 comments:

  1. 不好意思小鰻大請教
    為何我照你上面的方式
    把drawable目錄刪掉,
    剩下其它3個目錄(drawable - ldpi、drawable - mdpi、drawable - hdpi),
    且將繪好的mdpi圖形,
    丟進drawable - mdpi,
    如果程式發現現在使用的手機,
    是ldpi或hdpi時,
    系統會自動去換算放大或縮小,
    也不會讓原本設計給mdpi的圖片尺寸,
    在hdpi或ldpi中跑版。

    我用模擬器選擇HVGA320x480
    他並沒有把mdpi的圖調整成為其他版大小
    圖一樣超過版面
    我有哪裡沒設定到嗎?!
    謝謝

    ReplyDelete
  2. 不好意思,
    我最近比較忙,
    因此還抽不出時間實作一個專案來模擬你的問題,
    如果這個問題有點急,
    可能麻煩你再請教其它高手,
    或者再等我一下,
    等我比較有空再回答你。
    抱歉哦~

    ReplyDelete
  3. 不好意思 請教一下

    如果遇到不同比例的螢幕(如:16:9, 5:4)

    應該如何做最佳化呢?

    謝謝

    ReplyDelete
  4. 不好意思請問一下小鰻大大
    我目前在用多解析度的配置
    也有用HTC Flyer平板的解析度

    原本是抓drawable-mdpi
    但Flyer升級成android 3.2.1後
    它會去抓drawable-mdpi-480x320

    我百思不得其解
    不曉得為何會這樣

    底下列出我所有圖片的資料夾
    drawable-hdpi
    drawable-mdpi
    drawable-mdpi-480x320
    drawable-mdpi-1024x600
    drawable-mdpi-1232x800
    drawable-xhdpi

    請大大指導一下
    感激不盡/(-_-)\

    ReplyDelete
  5. Dear Blaze Yang,
    我研究了很久,發現Google官方出的APP
    一直在走精簡化設計,我想目的是要讓簡潔的Layout去蓋過各種解析度大小的畫面不易分配的缺點,讓畫面即使差很多,看起來都還是好看的…
    以上是個人認知哩

    ReplyDelete
  6. Dear 永仔
    Android3.2.1在Androidmanifest裡做了很多的更動,建議在官方文件中,看到哪些值的設定方式有受到新版的影響。

    ReplyDelete
  7. 不好意思 請問一下 那如果是拉內建Button和一些原件,要如何讓系統自動去判斷
    螢幕的寬和高呢?

    ReplyDelete
  8. 這篇解決了讓我不懂很久的解析度觀念,感謝~

    ReplyDelete
  9. 請問,自己剛接觸Android不到一年;在進行APP製作的時候會遇到UI設計人員的開版都是用PX來定義按鈕大小、物件間距與字型大小;
    例如以640x960 5吋螢幕的解析度來說,應該歸類為hdpi(應該沒錯吧@@?)
    想請教幾個問題:
    1. 如果是只製作了hdpi的圖片,我們能否強制要求在不同解析度(例如:mdpi, ldpi或是xhdpi)讓系統利用hdpi的圖片加以縮放? 還是只能乖乖地在不同資料夾中,製作另外三種縮放過後的實體圖片。

    2. 我僅知道圖片、按鈕或間距這種大小用dp以及文字用sp表示時,系統可針對不同解析度加以調整;而使用px時則不行...但這似乎不為UI人員所接受,認為目前這樣就好了...讓我提不出更多可以討論的話;多說了很多,最主要就是想問
    如果僅用PX來給予尺寸或是字型大小等等,能否有更多有風險的角度可以加以評估呢? 十分感謝~

    ReplyDelete
  10. 小鰻,為什麼我的是在手機畫面看起來正常,到了平板
    整個圖就變小了,
    我是想要,到圖片應該變大才對。

    ReplyDelete