開(kāi)篇
近日,在研究屏幕適配的問(wèn)題,由于涉及比較多概念,例如ppi、dpi、dip、px等等,在適配屏幕的時(shí)候經(jīng)常不得要領(lǐng),寫(xiě)此文章,做個(gè)總結(jié)。
相關(guān)名詞
屏幕尺寸: 也就是我們平時(shí)所說(shuō)的某某手機(jī)是幾寸屏, 比如HTC one V這款手機(jī)是3.7寸的, 這里的寸說(shuō)的是英寸(inch),國(guó)際上習(xí)慣使用的單位,1inch = 2.54cm,3.7寸指的是屏幕的對(duì)角線(xiàn)的長(zhǎng)度。
屏幕分辨率: 指屏幕的寬和高的像素?cái)?shù), 比如HTC one V是480x800的。
屏幕密度: 每英寸的像素?cái)?shù),比如HTC one V, 是252 px/inch。
px: 像素。一塊顯示屏是由很多的光點(diǎn)組成的,每一個(gè)光點(diǎn)就是一個(gè)像素。由于這些光點(diǎn)很小很密,想想看,在上面提到的3.7寸的手機(jī)上,橫向有480個(gè)光點(diǎn),縱向有800個(gè)光點(diǎn),所以顯示出來(lái)的文字或者圖片才很細(xì)膩平滑。
ppi: 和屏幕密度一個(gè)意思, 全稱(chēng)是pixel per inch. 是專(zhuān)業(yè)一點(diǎn)的叫法。
dpi: dot per inch,每英寸的點(diǎn)數(shù)。在電子顯示范疇內(nèi)它和PPI是一個(gè)意思。 只有在打印時(shí)這個(gè)縮寫(xiě)才有意義,在打印領(lǐng)域不存在 PPI的叫法,只說(shuō)DPI,它表示打印機(jī)每英寸打印幾個(gè)像素點(diǎn)。寬高同樣像素下,dpi越大,打印出來(lái)的圖案越小。
dip: 或者叫dp,這是開(kāi)發(fā)中特有的一種度量,稱(chēng)作屏幕無(wú)關(guān)像素, 它不表示任何具體的長(zhǎng)度或者像素點(diǎn), 這個(gè)值只有在 具體屏幕密度的手機(jī)上,才會(huì)被轉(zhuǎn)換為具體的像素值。 這個(gè)時(shí)候才會(huì)有實(shí)際意義。
dip在屏幕中顯示
首先看圖:


首先,假設(shè)我們需要設(shè)計(jì)一個(gè)屏幕寬的控件而不使用match_parent在這個(gè)參數(shù),在一個(gè)1280x720像素,5英寸的屏幕中,我們可以計(jì)算出該屏幕的dpi(ppi)=(12802+7202)^0.5 / 5 = 1468.60 / 5 = 293.72 , 根據(jù)上表可知:240dpi<293.72dpi<320dpi,所以該屏幕對(duì)應(yīng)的主流像素密度xhdpi,此時(shí)由圖2我們可知,在該屏幕設(shè)計(jì)1dip的長(zhǎng)度,其實(shí)際尺寸應(yīng)為2px。此時(shí),需要設(shè)計(jì)一個(gè)控件其寬為屏幕寬(720px),我們就可以將其width設(shè)置為720 / 2 = 360dip。
看到這里,你或許會(huì)有疑問(wèn):在不同屏幕尺寸,設(shè)計(jì)一個(gè)占據(jù)屏幕寬的控件,難道都需要這么麻煩嗎?也不一定是。
我們?cè)倥e一個(gè)常見(jiàn)的屏幕尺寸:1920x1080像素,5.5英寸的屏幕。通過(guò)計(jì)算得出dpi=400.53,屬于xxhdpi。當(dāng)我們?cè)O(shè)置360dip時(shí),屏幕的實(shí)際像素為540px剛好為屏幕的一半1080px。
那么,是否能得出360dip就是屏幕的寬呢?答案當(dāng)然是否定的,對(duì)于目前主流的屏幕分辨率例如1280x720像素5英寸(xhdpi),1920x1080像素5.5英寸(xxhdpi),360dip經(jīng)過(guò)計(jì)算得出恰好占據(jù)屏幕。但當(dāng)碰上某些奇葩屏幕分辨率時(shí)例如:1280x768像素,5寸(xhdpi)、1920x1152像素,5寸(xxhdpi),此時(shí)360dip分別對(duì)應(yīng)720px與1080px,此時(shí)顯然達(dá)不到屏幕的寬。
由此我們可以得出結(jié)論,對(duì)于一些主流像素,主流屏幕尺寸,參考xxx手機(jī),適配這些屏幕時(shí),用dip(dp)就能滿(mǎn)足我們的需要,但是對(duì)于市面上的奇葩分辨率及尺寸,我們得用其它手段適配屏幕(例如:采用百分比的方式適配)。
圖片在屏幕中的顯示
首先查看這副圖片:

我們可以舉個(gè)例子:
當(dāng)我們把一套適配1280x720像素的切圖放在xhdpi的drawable文件夾下(其它drawable文件夾沒(méi)有圖片),一個(gè)xxhdpi的設(shè)備在布局文件中引用了某個(gè)切圖,假設(shè)這個(gè)切圖的寬占據(jù)了360px(1280x720像素屏幕的一半),由于xxhdpi設(shè)備獲取到的圖片在xhdpi下,故系統(tǒng)會(huì)自動(dòng)放大該圖片為360px * 1.5 = 540px,此圖片剛好占據(jù)此xxhpi設(shè)備屏幕的一半。同理反過(guò)來(lái),一套1920x1080像素的切圖同樣可以適配xhdpi的屏幕。
但是,需要注意的是,如果要適配例如800x480像素的屏幕,這張圖片的顯示是達(dá)不到我們的預(yù)期的??梢耘e市面上的854x480像素的機(jī)型,這些機(jī)型往往在4寸到4.5寸之間,通過(guò)計(jì)算得出ppi在207.3~233.2之間,同屬于hdpi。當(dāng)該機(jī)型的某個(gè)控件引用了此圖片(控件是自適應(yīng)圖片大小),可以通過(guò)計(jì)算得出實(shí)際占據(jù)屏幕的像素為:360px * 3/4 =270px。很顯然,該圖片已經(jīng)超出屏幕的一半以上了。這種情況最好的解決辦法還是增加相應(yīng)的布局。
適配主流屏幕
我們查看2016年11月與12月的設(shè)備分辨率(友盟統(tǒng)計(jì)):


由統(tǒng)計(jì)我們可知:目前主要的屏幕寬的像素為720p、1080p、480p以及540p,如果需要適配主流屏幕,那么我們需要做的就是適配320dp的屏幕以及360dp的屏幕,對(duì)于這種差異,我們可以在layout-w320dp文件夾下創(chuàng)建相應(yīng)的文件即可。當(dāng)然由于w320dp主要對(duì)應(yīng)市面上480 * 800的機(jī)型,其屏幕比例為3:5,對(duì)于高度方向的差異也很明顯,如果整個(gè)界面是獨(dú)占式,無(wú)法上下滾動(dòng),那么我們還需要對(duì)高度方向進(jìn)行相應(yīng)的調(diào)整。
同樣,有些平板分辨率則是1920*1200(7英寸),屬于xhdpi,但是360dp的寬在屏幕上的只占據(jù)720px,顯然360dp并不是所有機(jī)型的屏幕寬。
如果你的app只針對(duì)主流機(jī)型的屏幕適配(屏幕寬為360dp,屏幕比例為16:9),那你大可不必創(chuàng)建多種布局文件去適配,但是如果你的目標(biāo)不僅僅是主流機(jī)型,那么就一定需要適配。
需要幾套切圖
對(duì)于現(xiàn)在屏幕設(shè)計(jì)需要給幾套切圖,看了大多數(shù)博客,總結(jié)出的結(jié)果是:可以?xún)H給出一套720 * 1280 的圖片,放在drawable-xhdpi的資源文件夾下。由于低dpi的設(shè)備讀取高dpi文件夾的屏幕會(huì)按比例縮小,高dpi的設(shè)備讀取低dpi文件夾的屏幕會(huì)按比例變大,看到這也許你會(huì)擔(dān)心:如果低dpi的設(shè)備讀取這些高dpi文件夾下的圖片會(huì)增加內(nèi)存消耗嗎?筆者起先也有疑惑,首先將圖片按3:4:8的比例分別放置在drawable-hdpi、drawable-xhdpi、drawable-xxhdpi文件夾下,圖片的寬高也按3:4:8的比例縮放,我們長(zhǎng)寬分別為:27x27:36x36:54x54。我們使用下面這個(gè)方法將代碼讀取到內(nèi)存中:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image_test);
int byteCount = bitmap.getByteCount();
Log.d("MainActivity", "byteCount: " + byteCount);
我們用xhdpi屏幕機(jī)型去執(zhí)行這段代碼,分為三種情況:
- 不刪除圖片
- 刪除drawable-xhdpi文件夾下圖片
- 繼續(xù)刪除drawable-xxhdpi文件夾下圖片
最后讀取的byteCount都為:5184(36*36*4、54*2/3*54*2/3*4、27*4/3*27*4/3*4)
由此我們可以總結(jié)出,一套圖片放置在相應(yīng)文件夾下,低dpi的設(shè)備讀取高dpi文件夾的圖片不會(huì)導(dǎo)致內(nèi)存消耗,但是如果你把本該放在drawable-xhdpi圖片放在drawable-hdpi文件夾下,那么將會(huì)消耗更多內(nèi)存,甚至?xí)?dǎo)致ImageView中顯示的圖片變大;如果反過(guò)來(lái)呢,本該放在drawable-xhdpi圖片放在drawable-xxhdpi文件夾下,那么就會(huì)加載的圖片比實(shí)際預(yù)期尺寸要小。
這樣做會(huì)使得xxhdpi的屏幕讀取到的圖片效果沒(méi)有基于1080p設(shè)計(jì)的效果好,所以有的博主推薦基于1080p的設(shè)計(jì),但是這樣也會(huì)使得apk的空間變大,這當(dāng)然也不是好事,魚(yú)和熊掌不可兼得,所以還是需要看實(shí)際情況再選擇哪套圖設(shè)計(jì)。
總結(jié)
360dp寬是目前主流機(jī)型的屏幕寬,但不是絕對(duì)的,對(duì)于一些奇葩分辨率的屏幕以及平板則不適用。
320dp寬是以前主流機(jī)型的屏幕寬,同樣也不是絕對(duì)的,目前市面上同樣有該種屏幕的機(jī)型,占據(jù)比例大概在3.5%,如果要作主流機(jī)型適配同樣不能忽略。
一套720p或者1080p的切圖足以應(yīng)對(duì)主流機(jī)型的屏幕適配問(wèn)題,且低dpi的屏幕讀取高dpi文件夾下的圖片,由于會(huì)自動(dòng)縮小相應(yīng)比例,所以?xún)?nèi)存不會(huì)比讀取相同dpi文件下的圖片更耗內(nèi)存。
感謝以下文章的參考:
http://www.android100.org/html/201505/24/149342.html
http://blog.csdn.net/xiebudong/article/details/37040263/
http://www.cocoachina.com/android/20151030/13971.html