如何適配Android手機屏幕

27 評論 40452 瀏覽 406 收藏 10 分鐘

Android適配是一個大坑,你可能早有耳聞。但是別人告訴你坑,然后你也說坑,肯定是無法令人信服的。我們做學問,不能光知其然不知所以然,適配問題到底有多坑,為什么坑,以及如何從坑里爬出來,就是我們今天要探討的話題了。

這還得從Android的開放性說起。不同于iOS,Android的設備廠商可以生產任意屏幕大小的手機、平板和TV,谷歌對此并沒有做任何限制。直接后果就是設備越來越多,大大小小的屏幕尺寸也是層出不窮。另一方面,程序員都有一個夢想,就是一套代碼走天下,誰都不想把美好青春浪費在應付各種奇葩的屏幕適配上去。所以說程序員一談適配色變,尤其是Android的適配,簡直比產品經理改需求還要痛苦。這里有兩張圖,你可以看下當前形勢多么嚴峻。

1

Android設備碎片化情況

2

Android設備屏幕尺寸情況

也就是說,我們開發一款Android App,就要對成千上萬種屏幕尺寸做適配嗎?非也。魔高一尺道高一丈,為了能又精準又省事兒的完成適配,這里有不少方法可以用,我們先從幾個基本的概念說起。

1、像素(px)和分辨率。

我們的顯示屏是由一個一個肉眼看不見但是放大鏡可以看見的小點點組成的,這些點點就是像素,是物理世界中存在的東西。分辨率是你的顯示屏一共有多少像素。我們平時說的分辨率是1920*1080,就是所謂的1080p,意思是顯示器上水平方向有1920個像素,垂直方向有1080個像素,乘起來大概是200W個像素。

2、屏幕密度(dpi)。

屏幕密度是對角線上每英寸的屏幕包含多少個像素。比如你手里的iPhone 6 plus,對角線有5.5英寸長,分辨率是1920*1080,那么根據勾股定理(還記得嗎,小學語文老師講過的哦),對角線上有2203個像素,屏幕密度就是2203/5.5=400,單位是dpi或者ppi,二者是一個意思。

在此基礎上,Google順便把手機按照屏幕的密度分了幾個檔次:

3

現在主流的手機,都可以找到自己所在的屏幕密度檔次。比如一般來說720p的手機是xhdpi,1080p的是xxhdpi。還有一種情況,比如同樣都是4英寸的480*800和4英寸的960*540,盡管實際算出來的dpi不一樣,但是都要歸到hdpi這一檔,dpi都變成了240,這是Android系統做的一種近似處理,目的是為了簡化計算。也就是說,雖然實際上手機的密度有很多種,但是大家會找到自己的近似區間,然后用區間的代表值去做運算。

3、密度無關像素(dp)

dp是一個虛擬的概念,是在程序運行的時候算出來的。怎么理解呢?Android設備那么多,分辨率也那么多,直接學iOS用px做單位肯定不行的。為此Google搞了一個叫dp的東西,換算公式是dp=(dpi/160)*px。也就是說,在密度為160dpi的屏幕上,1px就是1dp。依次類推,在320dpi的屏幕上,1dp就是2px。屏幕密度越大,1個dp對應的px也就越多。

根據前面講的屏幕密度區間,你可以記住這樣一個簡單的計算方法:

  • mdpi區間的手機,dp=px。
  • hdpi區間的手機,dp算px要乘以1.5。
  • xhdpi區間的手機,dp算px要乘以2。
  • xxhdpi區間的手機,dp算px要乘以3。
  • xxxhdpi區間的手機,dp算px要乘以4。

用dp有什么好處呢?假設我們現在有兩臺手機,一臺是1280*720,320dpi,一臺是1920*1080,480dpi。設計師同學給了一個標注是360px,放在第一臺手機上正好是屏幕寬度的一半,但是放在第二臺的手機上,則只有寬度的1/3了。這顯然是不行的?,F在設計師改成了180dp,那么根據公式,在320dpi的手機上,180dp=360px是屏幕寬度720px的一半。在480dpi的手機上,180dp=540px也是屏幕寬度1080px的一半。所以你看到了,dp是用來屏蔽手機的像素密度的差異的,相同dp的標注,在不同分辨率的屏幕上,實際大小都是一致的(從這個角度講,你可以把dp看做是一個類似厘米、英寸這樣的絕對的長度單位,大約160dp等于1英寸)。

相應的,在開發的時候,Google提供了一些資源目錄,你可以把對應大小的圖片放進去。

4

舉個例子,你想展示一張100dp*100dp的圖片,那么在mdpi目錄下,你需要放100px*100px的原圖。在xxxhdpi下,這張圖片就得是300px*300px。你的APP在運行的時候,如果需要加載這張圖片,系統就會根據當前手機的密度,去相應的資源目錄下去找。你可能會問,找不到怎么辦呢?比如當前是mdpi的手機,系統發現mdpi下沒有這張圖,就會去比mdpi更大的目錄找,然后進行縮放。實在找不到就去比mdpi更小的目錄找,找到之后再拉伸。

那么,設計師在出圖的時候,有兩種方法可以選。一是按照官方的推薦方法,在上面所有目錄下各放置一份同樣的圖片,根據dp和px的換算關系切成不同的大小,讓系統自動去尋找最合適的圖片。這種方法成倍的增加設計師的工作量不說,還會增加安裝包的體積,用戶下載的時候要多耗費流量,可能過不了隔壁產品同學這一關。第二種方法是選一個基準的屏幕密度,比如xhdpi,720p。所有的資源都放在這里,讓系統自動去縮放。這種方法呢,對于小屏幕的手機來說,因為要在運行的時候把一張大圖縮放成小圖,不如直接用小圖節省內存。對大屏幕的手機呢,比如你720p的圖拿到1080p的手機去顯示,肯定會因為縮放而失真。

綜合起來的話,我更傾向于第二種方法。具體選擇哪種屏幕密度做標準,你可以參考下Google官方的統計。

5

還有一些準則,有必要交代一下。

  1. 盡量是用dp,這是最基本的。
  2. 如果你使用xhdpi(一般是720p)為基準進行標注,注意它的屏幕寬度是360dp(720/2),而對于hdpi及以下的手機,比如480*800,屏幕寬度是480/1.5=320dp。此時如果你標注的長度超出320dp的話,最好換一種方式。
  3. 盡量用百分比和相對位置。Android的屏幕分辨率、屏幕密度實在太多了,dp也不是萬能的。

如果各位感興趣的話,下回講講iOS的屏幕適配。

#專欄作家#

給產品經理講技術,微信公眾號(pm_teacher),人人都是產品經理專欄作家。資深程序猿,專注客戶端開發若干年,對前端、后臺技術略懂,熱衷于對新的科技領域的探索。

本文原創發布于人人都是產品經理,未經許可,不得轉載。

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 圖裂了

    來自廣東 回復
  2. 最近做一個光標定位輸入框,彈出鍵盤的需求。公司的開發小哥哥說IOS需要適配很多機型,所以非常期待IOS的適配啊~

    來自廣東 回復
  3. 作者大佬,有個地方有點問題吧,1.按照計算方法,在xxxhdpi下,這張圖片就得是400px*400px把?

    來自上海 回復
    1. 是的,他搞錯了

      來自廣東 回復
  4. 寫得清晰易懂,問一下,文章后面提到的設計師出圖的兩種方法,除此之外,是否可考慮用SVG圖?這樣的話不同擔心大小,也不用擔心失真

    來自廣東 回復
  5. 沒看懂~??????

    回復
  6. 是否可以取xxxdpi的最大尺寸?雖然單張圖可能會稍微大點,但對于所有尺寸可能都適用,不用設計幾個尺寸,也不用擔心大屏會變形,綜合性價比高,不知道為什么不用這種方法,還請教下大家!

    回復
  7. 6666

    回復
  8. 想問一下,您的Google官方的統計數據是從哪里得到的?

    來自北京 回復
  9. 哥們寫的不錯

    回復
    1. 不錯。。

      來自廣東 回復
    2. +1

      來自廣東 回復
    3. +2

      來自廣東 回復
    4. +3

      來自廣東 回復
    5. +44

      來自廣東 回復
    6. +6

      來自廣東 回復
    7. 7

      來自廣東 回復
    8. +8

      來自廣東 回復
    9. +9

      來自浙江 回復
    10. 10

      來自福建 回復
    11. 這個回復樣式也是醉了

      來自福建 回復
    12. 怎么蓋樓

      來自上海 回復
    13. 城會玩

      來自北京 回復
  10. 哥們寫的不錯

    來自浙江 回復
  11. 適配問題真的很愁人,盡量用dp,設計人員每次給出大小時要換算成dp單位的么????

    來自北京 回復
    1. 產品規劃用dp,設計師出素材時要導出像素圖,這時還是要用px的。為了適配,一個素材出一套,一般在文件名后分別加上@2、@3對應不同分辨率的機型。一看文件名就知道是一套的,看后面的@x,就知道對應的分辨率。我們的設計原來用ps出素材,效率較低。后來來了一位設計總監,在他力推下用AI的畫板輸出功能,效率更高了。

      來自北京 回復
  12. ?? ?? 長姿勢了

    來自北京 回復