安卓屏幕--Android屏幕適配經驗談

http://blog.csdn.net/xiebudong/article/details/37040263

先來解釋一些相關的名詞:

屏幕尺寸:  也就是我們平時所說的某某手機是幾寸屏, 比如HTC one V這款手機是3.7寸的, 這裏的寸說的是英寸(inch),國際上習慣使用的單位,1inch = 2.54cm,3.7寸指的是屏幕的對角線的長度。

屏幕分辨率: 指屏幕的寬和高的像素數, 比如HTC one V是480*800的。

屏幕密度:   每inch的像素數,比如HTC one V, 是252 px/inch。 

px:  像素。一塊顯示屏是由很多的光點組成的,每一個光點就是一個像素。由於這些光點很小很密,想想看,在上面提到的3.7寸的手機上,橫向有480個光點,縱向有800個光點,所以顯示出來的文字或者圖片才很細膩平滑。

ppi: 和屏幕密度一個意思, 全稱是pixel per inch.  是專業一點的叫法.

dpi: dot per inch,每英寸的點數。在電子顯示範疇內它和PPI是一個意思。 只有在打印時這個縮寫纔有意義,在打印領域不存在 PPI的叫法,只說DPI,它表示打印機每英寸打印幾個像素點。寬高同樣像素下,dpi越大,打印出來的圖案越小。

dip: 或者叫dp,這是Android開發中特有的一種度量,稱作屏幕無關像素, 它不表示任何具體的長度或者像素點, 這個值只有在 具體屏幕密度的手機上,纔會被轉換爲具體的像素值。 這個時候纔會有實際意義。 具體怎麼轉換,接下來會講解。


下面貼出傳說中的HTC one V的截圖, 帶了相關尺寸的標註: (一個很老舊的手機,但是在480*800分辨率屆很有代表性)


對於一個新發布的手機,廠商一般會指明3個基本的參數:屏幕尺寸、分辨率和ppi。 根據這三個值我們就能算出這個顯示屏的長和寬各式多少。

比如:     

屏幕寬 = 480/252 ≈ 1.9 inch

屏幕高 = 800/252 ≈ 3.17 inch

注: 

對於顯示器來說, 橫向和縱向的密度是一樣的, 也就是說,在屏幕上任意截取一個正方形,它的橫向像素數=縱向像素數。

另外我們關心的一點是,這個手機的屏幕密度,對應的drawble目錄是哪一個。 這個我們很容易知道 ,是hdpi目錄。(怎麼就很容易知道了!? 別急別急, 下面就會說到)

這樣, 一個手機和顯示相關的參數我們就瞭然於胸了。


好了,我們進入正題。;-)


Android項目的res目錄下一般加上我們自己創建的,會有6個目錄,分別是:drawble  drawble-ldpi  drawble-mdpi  drawble-hdpi  drawble-xhdpi  drawble-xxhdpi, 這裏就不包括更爲特殊的drawble目錄了,(比如drawlbe-land-hdpi, 表示水平方向的高分辨率的圖片,這些都目錄不管多麼長,它們都是按一丁點規律匹配的, 我們的目的是, 從個別中發現規律,從而應用到整體)。

當一個apk運行起來時,Android系統會根據其所運行的手機的屏幕密度去相對應的圖片文件夾裏找指定名稱的圖片。 注意, 先去哪個目錄裏找,完全是根據這個手機的屏幕密度決定的。



其中注意兩點:

1, 中等分辨率,即mdpi的屏幕密度是160,他是標準的參考密度。所以計算比例的時候它的比例值是1. 其他屏幕密度的參考比例都是以這個爲依據。

2, 默認的drawble目錄(一般是自己建的),和mdpi是一樣的。將圖片放到這個目錄和放到drawble-mdpi目錄是一樣的效果。不過一般習慣性的放一些自定義selector或者點9的圖片在這裏。

現在我們來看, HTC one V手機的屏幕密度是252ppi, 那距離哪一個最靠近呢, 就是hdpi了。 所以當apk運行在這個手機上時,首先會去這個目錄找圖片。

下面是用常見的一些類型的手機總結的一個表格:


注意一點: 上面說的對應關係,都是首選目錄, 那如果首選目錄裏面找不到圖片呢? 


Android圖片選擇策略

上面說到, 如果屏幕所對應的文件夾沒有要找的圖片,怎麼辦。這是很常見的,我們開發項目時一般不會去爲每一個級別的屏幕去切一套圖片。那樣做只會讓apk很大。所以一般性的圖片我們只切一兩個典型密度屏幕的圖片。但是apk是有可能會運行在從ldpi到xxhdpi的各種級別的手機上。這個時候就需要根據一定的策略去尋找圖片了。

Android系統尋找圖片的步驟是這樣的:

1, 去屏幕密度對應的目錄去找。如果找到就拿來用。

2, 如果沒找到,就去比這個密度高一級的目錄裏面去找,如果找到就拿來用。

3, 如果沒找到就繼續往上找。以此類推。

4, 如果到了xxhdpi目錄還沒有找到的話,就會去比自身屏幕密度低一級的目錄去找,如果低一級的目錄>=hdpi,找到了就拿來用。

5, 如果沒找到, 就去mdpi目錄去找, 如果找到了,就拿來用。

6, 如果沒找到,就去默認的drawble目錄裏去找, 如果找到了就拿來用。

7 ,如果沒找到,再去最低的ldpi目錄裏去找。如果找到了,就拿來用。

8, 如果沒找到, 那就是沒找到了, 圖片無法顯示。(不過一般不會出現這種現象,因爲如果每個目錄都沒有這個圖片的話,你是編譯不過的)

這裏有兩點需要注意:

①  首先會去比自己密度高的目錄裏去找,這是因爲因爲系統相信,你在密度更高的目錄裏會放置分辨率更大的圖片,這樣的話這個圖片會被縮小,但同時顯示效果不會有損失,但是如果優先去低一級別的目錄去找的話, 找到的圖片就會被放大,這樣的話這個圖片就會被拉扯模糊了。

e.g. 同一張圖片,你在mdpi和xxhdpi目錄各放了一份, 這個應用你現在運行在hdpi的手機上, 那應用會選擇哪張圖片呢。答案是xxhdpi目錄裏的。即便hdpi離mdpi更近一點!

②,如果在mdpi裏找不到是不會直接去ldpi裏找的, 而是先去默認的drawble目錄裏找,這是drawble目錄和drawble-mdpi是一個級別的。

下面用一張流程圖來總結:

 

(注: 以上流程圖是我通過做實驗總結出來的,如有謬誤還望指出。)


Android系統對圖片的縮放規則


上文中提到如果在手機對應的目錄沒有找到圖片,就會按照一定的策略去其他目錄找,那找到了以後就原圖顯示麼? 非也。

對於放在不同目錄下的圖片, 系統會按照一定比例對原始的圖片進行放大或者縮小, 具體的放大縮小比例可參考下表, 圖片所在目錄和對應的屏幕密度是相同時圖片縮放比例爲1,也就是原圖顯示,而橫向的比例表示分別放在該密度手機上運行時圖片被縮放的比例。

對原始圖片的縮放倍數。



上表幾點值得注意的地方:

①, drawable目錄和drawable-mdpi目錄和dp到px的轉換關係是一樣的。 

②,當你放一個120px*180px的圖片到drawable-hdpi目錄,如果此應用運行在一個xhdpi的手機上,則這個圖片會被拉扯到160px*240px。

③, 最後一行dp->px, 說明了在代碼或者佈局文件中聲明一個dp值, 這個值在不同屏幕密度的手機中會被乘以不同的倍數。 比如你在佈局文件中寫了一個寬和高分別爲120dp和180dp的LinearLayout, 那麼當這個應用運行在xhdpi的手機上時(比如上面那個常見手機表中的中興U985手機),它的實際像素就會被轉換爲240px*360px。 如果運行在ldpi的手機上,就變成了90px*135px。 但是在這兩個手機中顯示的區域大小從肉眼看,是一模一樣大的。(這點作爲後面內容的一個引子,“看起來”一樣大,這就是Android的一個神奇的地方)

 

我們來做個試驗

試驗材料:

① 一張120px*180px的圖片


②  四部手機, 具體參數參考上面的一張表格。三星 Galaxy win pro 3218  (hdpi)、 HTC one V (hdpi)、 中興U985 (xhdpi)、Google Nexus 7 (xhdpi)。 

③  我在佈局文件裏聲明瞭3個View, 第一個位於左上角,是一個線性佈局,寬和高指定爲120dp*180dp(注意是dp哦), 第二個位於右上角,是一個ImageView,內容就是上面這張120px*180px的圖片, 第三個位於左下角也是一個線性佈局,固定寬高,是120px*180px。

我將這個圖片放到一個Android工程裏的drawable-hdpi目錄


從上面的那種縮放關係表中我們可以知道,圖片從hdpi目錄中取, 運行在hdpi手機上寬高保持原始值,,運行在xhdpi手機上,寬高會乘以4/3, 也就是說圖片會被拉扯變大, 但是圖片的實際顯示效果,即“視覺大小”怎麼樣呢。

下面是運行後的效果:



如圖: 黑色區域是120dp*180dp的View, 藍色區域是120px*180px的圖片, 灰色區域是120px*120px的View。

1, 可以看到使用dp的View(黑色區域)在不同分辨率,不同屏幕尺寸,不同屏幕密度的手機下,視覺大小看起來是一模一樣的。 

但是他們的實際像素值是不一樣的: 120dp*180dp -> (hdpi) -> 180px*270px, 而120dp*180dp ->(xhdpi)->  240px*360px。 由於屏幕密度的不同,縮放以後的像素可以顯示出一樣的視覺大小。

2, 藍色圖片的視覺大小也是一樣的, 由於圖片放到了hdpi目錄下, 所以前兩個手使用的是圖片的原始像素120px*180px, 而後兩個手機對圖片進行了放大, 參考上面的屏幕密度縮放關係表, 放大了4/3倍。  我通過對屏幕的截圖,測量下來的結果的確是放大了這麼多, 分別爲160px*240px。 由於屏幕密度的不同,它們顯示出來的視覺大小是相同的。

3, 但是使用固定像素值的View就沒那麼幸運了, 它在hdpi的手機上看起來要比在xhdpi的手機上大一些。 要是在屏幕密度相差更大的手機上看的話, 這個區域的大小會相差很大。 這就是爲什麼Android推薦使用dp作爲View的尺寸,而不是真實像素的原因了。

4,  經過反覆試驗,(實驗結果就不貼圖了,很多),得出一個結論,使用哪個目錄下的圖片(前提是圖片只放在某一個目錄中),在所有,不管是分辨率還是屏幕尺寸還是屏幕密度,3個參數都在改變的情況下,圖片顯示的視覺大小都和運行在這個目錄對應屏幕密度手機上時的大小是一樣的。 


UI給工程師切多大圖是合適的。


說說我之前走的冤枉路吧。

在之前, 設計師的交互和視覺設計都是基於480*800的界面, 切圖的時候會以480*800爲基礎切一版, 然後在給所切圖片的寬和高乘上個4/3,然後在出一版。

比如同一個120*180的圖片, 就會出兩個版本, 一個是120*180的一個是160*240的。分別放到hdpi目錄和xhdpi目錄。

喫到的苦頭是,UI很累, apk很大。T^T

這番探究下來, 發現直接基於720*1280的視覺稿切一版圖片就可以了。 將圖片只放到xhdpi目錄中,這樣系統會在不同密度屏幕的手機中對圖片進行合理的縮放, 而之前這個縮放工作竟然是人工完成的!

另: 如果想在xxhdpi的手機上顯示的很好, 也可以基於1080P的屏幕設計, 這樣的話就兼容所有低密度屏幕的手機, 而且也不會出現圖片被拉扯的現象。

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