Android 屏幕完美適配方案(轉(zhuǎn)載)

轉(zhuǎn)載地址:https://mp.weixin.qq.com/s/e26d6s3hpWJOmhA4AUqRbQ?utm_source=androidweekly.cn&utm_medium=website

image

為什么要適配

由于Android系統(tǒng)的開放性,任何用戶、開發(fā)者、硬件廠商、運(yùn)營(yíng)商都可以對(duì)Android系統(tǒng)和硬件進(jìn)行定制,修改成他們想要的樣子。

但是這種“碎片化”到達(dá)什么程度呢?

image

以上每一個(gè)矩形都代表一種機(jī)型,且它們屏幕尺寸、屏幕分辨率大相徑庭。隨著Android設(shè)備的增多,設(shè)備碎片化、品牌碎片化、系統(tǒng)碎片化、屏幕碎片化的程度也在不斷加深。

為了讓我們的Android應(yīng)用在各式各樣的手機(jī)上運(yùn)行的時(shí)候,能夠保持界面效果一直,所以,我們需要對(duì)各種手機(jī)屏幕進(jìn)行適配!

概念

1、像素(px)

通常所說(shuō)的像素,就是CCD/CMOS上光電感應(yīng)元件的數(shù)量,一個(gè)感光元件經(jīng)過(guò)感光,光電信號(hào)轉(zhuǎn)換,A/D轉(zhuǎn)換等步驟以后,在輸出的照片上就形成一個(gè)點(diǎn),我們?nèi)绻延跋穹糯髷?shù)倍,會(huì)發(fā)現(xiàn)這些連續(xù)色調(diào)其實(shí)是由許多色彩相近的小方點(diǎn)所組成,這些小方點(diǎn)就是構(gòu)成影像的最小單位“像素”(Pixel)。

簡(jiǎn)而言之,像素就是手機(jī)屏幕的最小構(gòu)成單元

2、分辨率

手機(jī)在橫向、縱向上的像素點(diǎn)數(shù)總和,一般描述成 寬*高 ,

橫向像素點(diǎn)個(gè)數(shù)縱向像素點(diǎn)個(gè)數(shù)*。

3、屏幕尺寸(in)

手機(jī)對(duì)角線的物理尺寸,單位 英寸(inch),一英寸大約2.54cm,常見(jiàn)的尺寸有4.7寸、5寸、5.5寸、6寸

4、屏幕像素密度(dpi)

每英寸長(zhǎng)度上像素點(diǎn)個(gè)數(shù)。

例如每英寸內(nèi)有160個(gè)像素點(diǎn),則其像素密度為160dpi。

公式: 像素密度=像素/尺寸 (dpi=px/in)

5、標(biāo)準(zhǔn)屏幕像素密度(mdpi)

每英寸長(zhǎng)度上還有160個(gè)像素點(diǎn),即稱為標(biāo)準(zhǔn)屏幕像素密度(mdpi)。

6、像素密度等級(jí)

手機(jī)真實(shí)像素密度與標(biāo)準(zhǔn)屏幕像素密度(160dpi)的比值。官方給出的0.75、1、1.5、2、3、4,即對(duì)應(yīng)120dpi、160dpi、240dpi、320dpi、480dpi、640dpi。

7、密度無(wú)關(guān)像素(dp)

density-independent pixel,叫dp或dip,與終端上的實(shí)際物理像素點(diǎn)無(wú)關(guān)??梢员WC在不同屏幕像素密度的設(shè)備上顯示相同的效果,是安卓特有的長(zhǎng)度單位。

8、獨(dú)立比例像素(sp)

scale-independent pixel,叫sp或sip,字體大小專用單位,可根據(jù)字體大小首選項(xiàng)進(jìn)行縮放;

推薦使用12sp、14sp、18sp、22sp作為字體大小,不推薦使用奇數(shù)和小數(shù),容易造成精度丟失,12sp以下字體太小。

9、尺寸、像素、像素密度關(guān)系

image

10、px與dp關(guān)系

像素=dp像素密度等級(jí),即px=dp(dpi/160)**

對(duì)哪些設(shè)備適配

注意進(jìn)行Android設(shè)備的屏幕適配操作,不是單單對(duì)屏幕尺寸多樣的各種設(shè)備進(jìn)行的適配,在諸多的物理尺寸的背后是屏幕的分辨率,現(xiàn)在市面上占比最多的六種分辨率:480800、320480、480854、540960、7201280、10801920。在日常適配中只要做好對(duì)這幾個(gè)設(shè)備的適配,就能很好的適配其他機(jī)型。但是在這幾種分辨率的背后存在的更為根本的數(shù)據(jù)是設(shè)備的屏幕像素密度。在Google文檔中對(duì)于屏幕的像素密度進(jìn)行了幾種規(guī)定!

另外也需注意對(duì)安卓平板、安卓電視等大尺寸、超大尺寸設(shè)備的適配。

image
image

如何適配

1、適配誤區(qū)

在進(jìn)行適配的時(shí)候,人們總是關(guān)注于:代碼、Layout、Dimens、圖片、權(quán)重,這幾種適配方式并不是屏幕適配的全部方案,除此之外還存在多種小細(xì)節(jié)來(lái)實(shí)現(xiàn)屏幕適配。

如何理解使用dp為單位進(jìn)行適配?:

image.gif

但是,使用密度無(wú)關(guān)像素(dp)也不能做到適配所有屏幕!

2、造成誤差原因

在長(zhǎng)期的Android發(fā)展過(guò)程中,由于Android設(shè)備的增多,Google制定的屏幕密度標(biāo)準(zhǔn)(mdpi、hdpi、ldpi等),在眾多廠家的生產(chǎn)過(guò)程中,已經(jīng)被打破,人們沒(méi)有生產(chǎn)數(shù)完全符合屏幕密度標(biāo)準(zhǔn)的Android設(shè)備,對(duì)于真實(shí)手機(jī)的屏幕密度值,是在Google標(biāo)準(zhǔn)的周圍浮動(dòng)變化的,但是不乏存在一些廠商生產(chǎn)的設(shè)備偏離Google的屏幕密度標(biāo)準(zhǔn)比較大,這個(gè)時(shí)候再使用dp作為單位就不能完完全全的完成適配操作?。╠p只有在大家標(biāo)準(zhǔn)統(tǒng)一的情況下才有更好的發(fā)展)

在所有計(jì)算公式中存在誤差:在計(jì)算真實(shí)像素密度時(shí)運(yùn)用了開方運(yùn)算和除法運(yùn)算,導(dǎo)致所得結(jié)果存在誤差。

理論計(jì)算造成的誤差:

在計(jì)算對(duì)角線上像素點(diǎn)個(gè)數(shù)時(shí),我們使用勾股定理計(jì)算得出,但實(shí)則存在誤差:

  • 若將像素長(zhǎng)度當(dāng)做1,分辨率指的是橫縱向上的1的個(gè)數(shù),計(jì)算記過(guò)表示的是對(duì)角線上有多少個(gè)1,但理論上對(duì)角線上 根號(hào)2 的個(gè)數(shù)才是像素點(diǎn)的個(gè)數(shù)!

  • 屏幕對(duì)角線并不會(huì)和像素對(duì)角線重合,使計(jì)算結(jié)果存在誤差。

image.gif

3、ldpi、mdpi、hdpi、xhdpi、xxhdpi的使用

官方截圖:

image.gif
image.gif

4、使用wrap_content、match_parent、權(quán)重

要確保布局的靈活性并適應(yīng)各種尺寸的屏幕,應(yīng)使用 “wrap_content” 、“match_parent”和權(quán)重控制某些視圖組件的寬度和高度。

使用 “wrap_content”,系統(tǒng)就會(huì)將視圖的寬度或高度設(shè)置成所需的最小尺寸以適應(yīng)視圖中的內(nèi)容,而 “match_parent”(在低于 API 級(jí)別 8 的級(jí)別中稱為 “fill_parent”)則會(huì)展開組件以匹配其父視圖的尺寸。

如果使用 “wrap_content” 和 “match_parent” 尺寸值而不是硬編碼的尺寸,視圖就會(huì)相應(yīng)地僅使用自身所需的空間或展開以填滿可用空間。此方法可讓布局正確適應(yīng)各種屏幕尺寸和屏幕方向。

5、使用相對(duì)布局,不要使用絕對(duì)布局

我們大部分時(shí)候使用的都是線性布局、相對(duì)布局和幀布局,絕對(duì)布局由于適配性極差,所以極少使用。

關(guān)于布局的使用應(yīng)該具體情況具體分析,在進(jìn)行電視機(jī)頂盒的開發(fā)中就是使用的是絕對(duì)布局。

6、使用限定符進(jìn)行適配操作

使用尺寸限定符——large

使用最小寬度限定符——swdp

使用屏幕方向限定符

7、多套layout適配

res/values/layouts.xml:

res/values-sw600dp-land/layouts.xml:

res/values-sw600dp-port/layouts.xml:

res/values-large-land/layouts.xml:

res/values-large-port/layouts.xml:

8、使用自動(dòng)拉伸位圖

支持各種屏幕尺寸通常意味著您的圖片資源還必須能適應(yīng)各種尺寸。例如,無(wú)論要應(yīng)用到什么形狀的按鈕上,按鈕背景都必須能適應(yīng)。

如果在可以更改尺寸的組件上使用了簡(jiǎn)單的圖片,您很快就會(huì)發(fā)現(xiàn)顯示效果多少有些不太理想,因?yàn)橄到y(tǒng)會(huì)在運(yùn)行時(shí)平均地拉伸或收縮您的圖片。解決方法為使用自動(dòng)拉伸位圖,這是一種格式特殊的 PNG 文件,其中會(huì)指明可以拉伸以及不可以拉伸的區(qū)域。

.9的制作,實(shí)際上就是在原圖片上添加1px的邊界,然后按照我們的需求,把對(duì)應(yīng)的位置設(shè)置成黑色線,系統(tǒng)就會(huì)根據(jù)我們的實(shí)際需求進(jìn)行拉伸。

9、普通圖片處理

稍后會(huì)詳細(xì)介紹。

10、dimens使用

image.gif

如上圖,我將市面上各分辨率下的屏幕尺寸,取了平均數(shù),算出對(duì)應(yīng)的真實(shí)的屏幕像素密度,與理論要求的屏幕像素密度作了對(duì)比,比值在倒數(shù)第二列。發(fā)現(xiàn):(干貨要來(lái)了?。┱鎸?shí)像素密度與理論像素密度的比值大致分為兩類,取其平均數(shù),一類在1.15左右,另一類則在0.89左右。巧了,它們兩類正好各自對(duì)應(yīng)w320dp和w360dp的寬度限定符!所以,dimens只需寫兩套即可(values-w320dp、values-w360dp),其name與真實(shí)數(shù)值的比值就是剛剛我們算出的兩個(gè)平均數(shù)! 以后我們就不需要對(duì)應(yīng)各種分辨率寫多套dimens了,兩套dimens即可。

image

圖片處理

1、logo

image

logo需要3636、4848、7272、9696、144144、192192px,圖片使用正方形形狀,在某些機(jī)型上面,會(huì)自動(dòng)顯示為圓角正方形;

Android8.0以后,系統(tǒng)增加了logo點(diǎn)擊效果和動(dòng)畫,可按以上尺寸制作圓形logo,但圖片必須為正方形,圓形以外區(qū)域透明。

2、普通圖片

image
image

UI切圖只需按照720*1280,4.7寸屏幕切圖即可;

應(yīng)為iphone6等分辨率、尺寸、像素密度都與要求接近,可使用IOS的2x圖代替。

image

3、純色圖、.9圖

純色按鈕或漸變按鈕可使用代碼設(shè)置顏色或.9圖實(shí)現(xiàn),不必用圖片作為背景。

4、動(dòng)畫、自定義view、shape

可以使用代碼進(jìn)行控制和展示多種視圖,如patch動(dòng)畫替代幀動(dòng)畫。

5、ImageView的ScaleType

關(guān)于ScaleType請(qǐng)參考這里: http://blog.csdn.net/jiashuai94/article/details/77673625

其他

1、代碼適配

在代碼中使用Google提供的API對(duì)設(shè)備的屏幕寬度進(jìn)行測(cè)量,然后按照需求進(jìn)行設(shè)置。

幾個(gè)主要使用的API:

對(duì)于當(dāng)前控件的寬高設(shè)置,需要做的操作是首先要獲取到該控件的父控件,使用父控件對(duì)當(dāng)前控件的寬高進(jìn)行設(shè)置操作!

API

DisplayMetrics metrics = new DisplayMetrics ();

getWindowManager().getDefaultDisplay().getMetrics(metrics);

手機(jī)對(duì)應(yīng)的寬高:

Constants.screenHeight= metrics.heightDixels;

Constants.screenWidth= metrics.widthDixels;

RelativeLayout.LayoutParams=new RelativeLayout.LayoutParams();

(int)( Constants.screenHeight*0.5+0.5f);

(int)( Constants.screenWidth *0.5+0.5f);

在上面的兩個(gè)計(jì)算操作中最后加上0.5f的作用是:進(jìn)行float強(qiáng)轉(zhuǎn)到int類型的時(shí)候會(huì)出現(xiàn)都是精度的問(wèn)題。當(dāng)使用Java代碼進(jìn)行寬高設(shè)置的時(shí)候,假如出現(xiàn)320.2dp這樣的數(shù)據(jù)此時(shí)直接進(jìn)行int得到的值是320;但是假如出現(xiàn)320.7這樣的數(shù)據(jù)的時(shí)候,由于int的計(jì)算規(guī)則,會(huì)直接強(qiáng)轉(zhuǎn)為320,但是從實(shí)際出發(fā),這個(gè)時(shí)候的值取321更為合適。

所以在計(jì)算的最后直接加0.5,這樣一來(lái),320.2+0.5=320.7,進(jìn)行數(shù)據(jù)的強(qiáng)轉(zhuǎn)操作得到的數(shù)據(jù)是320,320.7+0.5=321.2,進(jìn)行數(shù)據(jù)強(qiáng)轉(zhuǎn)操作得到的數(shù)據(jù)是321,這樣一來(lái)得到的數(shù)據(jù)就和實(shí)際預(yù)想的更為接近??!

2、接口配合

本地加載圖片前判斷手機(jī)分辨率或像素密度,向服務(wù)器請(qǐng)求對(duì)應(yīng)級(jí)別圖片。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容