1. 程式人生 > >Android 開發:(九)Android螢幕適配經驗談

Android 開發:(九)Android螢幕適配經驗談

1.名詞解釋

  1. 螢幕尺寸:

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

  2. 螢幕解析度:

    指螢幕的寬和高的畫素數, 比如HTC one V是480*800的。

  3. 螢幕密度:

    每inch的畫素數,比如HTC one V, 是252 px/inch。

  4. px:

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

  5. ppi:

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

  6. dpi:

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

  7. dip:

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

下面貼出傳說中的HTC one V的截圖, 帶了相關尺寸的標註: (一個很老舊的手機,但是在480*800解析度屆很有代表性)
這裡寫圖片描述

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

比如:

螢幕寬 = 480/252 ≈ 1.9 inch
螢幕高 = 800/252 ≈ 3.17 inch

注:

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

另外我們關心的一點是:

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

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

2.res/drawble 結構

res/drawble

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是一個級別的。

下面用一張流程圖來總結:
這裡寫圖片描述

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

3. 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的螢幕設計, 這樣的話就相容所有低密度螢幕的手機, 而且也不會出現圖片被拉扯的現象。

轉載於:http://blog.csdn.net/xiebudong/article/details/37040263/#t0