如何適配Android手機(jī)屏幕

27 評(píng)論 40485 瀏覽 406 收藏 10 分鐘

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

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

1

Android設(shè)備碎片化情況

2

Android設(shè)備屏幕尺寸情況

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

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

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

2、屏幕密度(dpi)。

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

在此基礎(chǔ)上,Google順便把手機(jī)按照屏幕的密度分了幾個(gè)檔次:

3

現(xiàn)在主流的手機(jī),都可以找到自己所在的屏幕密度檔次。比如一般來說720p的手機(jī)是xhdpi,1080p的是xxhdpi。還有一種情況,比如同樣都是4英寸的480*800和4英寸的960*540,盡管實(shí)際算出來的dpi不一樣,但是都要?dú)w到hdpi這一檔,dpi都變成了240,這是Android系統(tǒng)做的一種近似處理,目的是為了簡(jiǎn)化計(jì)算。也就是說,雖然實(shí)際上手機(jī)的密度有很多種,但是大家會(huì)找到自己的近似區(qū)間,然后用區(qū)間的代表值去做運(yùn)算。

3、密度無關(guān)像素(dp)

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

根據(jù)前面講的屏幕密度區(qū)間,你可以記住這樣一個(gè)簡(jiǎn)單的計(jì)算方法:

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

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

相應(yīng)的,在開發(fā)的時(shí)候,Google提供了一些資源目錄,你可以把對(duì)應(yīng)大小的圖片放進(jìn)去。

4

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

那么,設(shè)計(jì)師在出圖的時(shí)候,有兩種方法可以選。一是按照官方的推薦方法,在上面所有目錄下各放置一份同樣的圖片,根據(jù)dp和px的換算關(guān)系切成不同的大小,讓系統(tǒng)自動(dòng)去尋找最合適的圖片。這種方法成倍的增加設(shè)計(jì)師的工作量不說,還會(huì)增加安裝包的體積,用戶下載的時(shí)候要多耗費(fèi)流量,可能過不了隔壁產(chǎn)品同學(xué)這一關(guān)。第二種方法是選一個(gè)基準(zhǔn)的屏幕密度,比如xhdpi,720p。所有的資源都放在這里,讓系統(tǒng)自動(dòng)去縮放。這種方法呢,對(duì)于小屏幕的手機(jī)來說,因?yàn)橐谶\(yùn)行的時(shí)候把一張大圖縮放成小圖,不如直接用小圖節(jié)省內(nèi)存。對(duì)大屏幕的手機(jī)呢,比如你720p的圖拿到1080p的手機(jī)去顯示,肯定會(huì)因?yàn)榭s放而失真。

綜合起來的話,我更傾向于第二種方法。具體選擇哪種屏幕密度做標(biāo)準(zhǔn),你可以參考下Google官方的統(tǒng)計(jì)。

5

還有一些準(zhǔn)則,有必要交代一下。

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

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

#專欄作家#

給產(chǎn)品經(jīng)理講技術(shù),微信公眾號(hào)(pm_teacher),人人都是產(chǎn)品經(jīng)理專欄作家。資深程序猿,專注客戶端開發(fā)若干年,對(duì)前端、后臺(tái)技術(shù)略懂,熱衷于對(duì)新的科技領(lǐng)域的探索。

本文原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)許可,不得轉(zhuǎn)載。

更多精彩內(nèi)容,請(qǐng)關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號(hào)或下載App
評(píng)論
評(píng)論請(qǐng)登錄
  1. 圖裂了

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

    來自廣東 回復(fù)
  3. 作者大佬,有個(gè)地方有點(diǎn)問題吧,1.按照計(jì)算方法,在xxxhdpi下,這張圖片就得是400px*400px把?

    來自上海 回復(fù)
    1. 是的,他搞錯(cuò)了

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

    來自廣東 回復(fù)
  5. 沒看懂~??????

    回復(fù)
  6. 是否可以取xxxdpi的最大尺寸?雖然單張圖可能會(huì)稍微大點(diǎn),但對(duì)于所有尺寸可能都適用,不用設(shè)計(jì)幾個(gè)尺寸,也不用擔(dān)心大屏?xí)冃?,綜合性價(jià)比高,不知道為什么不用這種方法,還請(qǐng)教下大家!

    回復(fù)
  7. 6666

    回復(fù)
  8. 想問一下,您的Google官方的統(tǒng)計(jì)數(shù)據(jù)是從哪里得到的?

    來自北京 回復(fù)
  9. 哥們寫的不錯(cuò)

    回復(fù)
    1. 不錯(cuò)。。

      來自廣東 回復(fù)
    2. +1

      來自廣東 回復(fù)
    3. +2

      來自廣東 回復(fù)
    4. +3

      來自廣東 回復(fù)
    5. +44

      來自廣東 回復(fù)
    6. +6

      來自廣東 回復(fù)
    7. 7

      來自廣東 回復(fù)
    8. +8

      來自廣東 回復(fù)
    9. +9

      來自浙江 回復(fù)
    10. 10

      來自福建 回復(fù)
    11. 這個(gè)回復(fù)樣式也是醉了

      來自福建 回復(fù)
    12. 怎么蓋樓

      來自上海 回復(fù)
    13. 城會(huì)玩

      來自北京 回復(fù)
  10. 哥們寫的不錯(cuò)

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

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

      來自北京 回復(fù)
  12. ?? ?? 長(zhǎng)姿勢(shì)了

    來自北京 回復(fù)