為什么要做適配
? ??????由于Android系統(tǒng)的開放性,任何用戶筑公、開發(fā)者雳窟、運(yùn)營(yíng)商都可以對(duì)Android進(jìn)行定制,于是導(dǎo)致:?
1匣屡、Android系統(tǒng)碎片化:小米定制的MIUI封救、魅族定制的flyme、華為定制的EMUI等等
2捣作、Android機(jī)型屏幕尺寸碎片化:5寸誉结、5.5寸、6寸等等
3券躁、Android屏幕分辨率碎片化:320x480惩坑、480x800、720x1280嘱朽、1080x1920
也就是Android碎片化并不局限于手機(jī)屏幕旭贬,??為了保證用戶獲得一致的用戶體驗(yàn)效果。
每一個(gè)方框代表一種 Android 設(shè)備的屏幕搪泳,顏色越深稀轨,這種尺寸的屏幕也就越多:
相關(guān)適配值
????????1、屏幕尺寸(英寸):是指屏幕對(duì)角線的長(zhǎng)度岸军,單位英寸奋刽。1英寸 = 2.54cm。?
? ??????2艰赞、屏幕分辨率(px):是指屏幕橫向和縱向像素點(diǎn)數(shù)佣谐,單位px,1px = 1物理像素方妖,UI?設(shè)計(jì)師的設(shè)計(jì)圖會(huì)以px作為統(tǒng)一的計(jì)量單位狭魂。
? ? ? ? 3、屏幕像素密度(dpi):是指每英寸上的像素點(diǎn)數(shù)、單位dpi雌澄、與像素?zé)o關(guān)的單位斋泄,像素密度是清晰度很重要的一個(gè)概念:即像素密度越高(dpi)代表顯示屏能夠以更高的密度顯示圖像
????????4、獨(dú)立密度像素(dp):意思就是與density密度(dpi)無關(guān)镐牺,可以保證在不同屏幕像素密度的設(shè)備上顯示相同的效果(px=dp*(dpi/160))炫掐。
? ? ? ? 5、屏幕尺寸睬涧、分辨率募胃、像素密度三者關(guān)系:sqrt(1920^2 + 1080^2) / 屏幕尺寸 (三角函數(shù)--勾股定理)
Android資源下的mdpi,hdpi畦浓,xhdpi痹束,xxhdpi,xxxhdpi如何計(jì)算和區(qū)分:目標(biāo)的像素密度宅粥、資源所在的像素密度参袱,得到一個(gè)值,然后根據(jù)這個(gè)值對(duì)圖片資源寬高做縮放處理秽梅,以便達(dá)到最佳顯示效果。(mipmap和drawable-xx區(qū)別)
? ? ? ? 1剿牺、mipmap目錄的圖標(biāo)會(huì)忽略屏幕密度企垦,回去匹配大一點(diǎn)的,然后系統(tǒng)自動(dòng)對(duì)圖片進(jìn)行縮放晒来,從而優(yōu)化顯示和節(jié)省資源下存放的資源:launcher icons钞诡、action bar and tab icons、Notification icons
? ? ? ?2湃崩、drawable-xhdpi:如果圖片放在drawable-xxxhdpi文件夾下面荧降,而系統(tǒng)是xhdpi的話,它會(huì)認(rèn)為這張圖是為更高密度的設(shè)備所設(shè)計(jì)的攒读,如果直接將這張圖在當(dāng)前設(shè)備上使用就有可能會(huì)出現(xiàn)像素過高的情況朵诫,于是會(huì)自動(dòng)幫我們做一個(gè)縮小的操作。建議存放目錄根據(jù)產(chǎn)品給的設(shè)計(jì)圖而定薄扁,不要浪費(fèi)不必要的內(nèi)存
今日頭條屏幕適配方案
上面已經(jīng)告知今日頭條屏幕適配方案的核心原理在于剪返,根據(jù)以下公式算出?density
當(dāng)前設(shè)備屏幕總寬度(單位為像素)/ 設(shè)計(jì)圖總寬度(單位為 dp) = density
density?的意思就是?1 dp?占當(dāng)前設(shè)備多少像素
????????今日頭條適配方案默認(rèn)項(xiàng)目中只能以高或?qū)捴械囊粋€(gè)作為基準(zhǔn),進(jìn)行適配邓梅,為什么不以高為基準(zhǔn)脱盲,寬以寬為基準(zhǔn),同時(shí)進(jìn)行適配呢大部分市面上的?Android?設(shè)備的屏幕高寬比都不一致日缨,特別是現(xiàn)在大量全面屏的問世钱反,這個(gè)問題更加嚴(yán)重,不同廠商推出的全面屏手機(jī)的屏幕高寬比都可能不一致這時(shí)我們只以高或?qū)捚渲械囊粋€(gè)作為基準(zhǔn)進(jìn)行適配,就會(huì)有效的避免布局在高寬比不一致的屏幕上出現(xiàn)變形的問題面哥。
density
density在每個(gè)設(shè)備上都是固定的哎壳,DPI / 160 = density,屏幕的總 px 寬度 / density = 屏幕的總 dp 寬度
設(shè)備 1幢竹,屏幕寬度為1080px耳峦,480DPI,屏幕總dp寬度為1080 / (480 / 160) = 360dp
設(shè)備 2焕毫,屏幕寬度為1440蹲坷,560DPI,屏幕總dp寬度為1440 / (560 / 160) = 411dp
可以看到屏幕的總dp寬度在不同的設(shè)備上是會(huì)變化的邑飒,但是我們?cè)诓季种刑顚懙?b>dp值卻是固定不變的
????????這會(huì)導(dǎo)致什么呢循签?假設(shè)我們布局中有一個(gè)View的寬度為100dp,在設(shè)備 1 中 該View的寬度占整個(gè)屏幕寬度的27.8%(100 / 360 = 0.278)疙咸,但在設(shè)備 2 中該View的寬度就只能占整個(gè)屏幕寬度的24.3%(100 / 411 = 0.243)县匠,可以看到這個(gè)View在像素越高的屏幕上,dp值雖然沒變撒轮,但是與屏幕的實(shí)際比例卻發(fā)生了較大的變化乞旦,所以肉眼的觀看效果,會(huì)越來越小题山,這就導(dǎo)致了傳統(tǒng)的填寫dp的屏幕適配方式產(chǎn)生了較大的誤差兰粉。
為什么傳統(tǒng)的dp適配不行那? 原始的density = dpi / 160;? (為什么是160)
屏幕的總 px 寬度 / density = 屏幕的總 dp 寬度
在這個(gè)公式中我們要保證屏幕的總 dp 寬度和設(shè)計(jì)圖總寬度一致顶瞳,并且在所有分辨率的屏幕上都保持不變玖姑,我們需要怎么做呢?屏幕的總 px 寬度每個(gè)設(shè)備都不一致慨菱,這個(gè)值是肯定會(huì)變化的焰络,這時(shí)今日頭條的公式就派上用場(chǎng)了
當(dāng)前設(shè)備屏幕總寬度(單位為像素)/? 設(shè)計(jì)圖總寬度(單位為 dp) = density??
優(yōu)點(diǎn):
1、成本非常低符喝,操作非常簡(jiǎn)單闪彼,使用該方案后在頁面布局時(shí)不需要額外的代碼和操作
2、侵入性非常低洲劣,該方案和項(xiàng)目完全解耦备蚓,在項(xiàng)目布局時(shí)不會(huì)依賴哪怕一行該方案的代碼,而且使用的還是Android官方的API囱稽,意味著當(dāng)你遇到什么問題無法解決郊尝,想切換為其他屏幕適配方案時(shí),基本不需要更改之前的代碼
3战惊、可適配三方庫的控件和系統(tǒng)的控件(流昏,Dialog、Toast等所有系統(tǒng)控件都可以適配),由于修改的density在整個(gè)項(xiàng)目中是全局的况凉,所以只要一次修改谚鄙,項(xiàng)目中的所有地方都會(huì)受益
4、不會(huì)有任何性能的損耗
缺點(diǎn):
坑一:當(dāng)某個(gè)系統(tǒng)控件或三方庫控件的設(shè)計(jì)圖尺寸和和我們項(xiàng)目自身的設(shè)計(jì)圖尺寸差距非常大時(shí)刁绒,這個(gè)問題就越嚴(yán)重
坑二:修改系統(tǒng)字體的時(shí)候字體大小未改變
坑三:系統(tǒng)自帶的吐司闷营,對(duì)話框都變形
坑四:webview 加載后 density 復(fù)原
smallestWidth適配方案
優(yōu)點(diǎn):
1、穩(wěn)定知市,極低概率出現(xiàn)意外
2傻盟、不會(huì)有任何性能的損耗
3、適配范圍可自由控制嫂丙,不會(huì)影響其他三方庫
4娘赴、在插件的配合下,學(xué)習(xí)成本低
缺點(diǎn):
1跟啤、在布局中引用dimens的方式诽表,雖然學(xué)習(xí)成本低,但是在日常維護(hù)修改時(shí)較麻煩/
2隅肥、侵入性高竿奏,如果項(xiàng)目想切換為其他屏幕適配方案,因?yàn)槊總€(gè)Layout文件中都存在有大量dimens的引用腥放,這時(shí)修改起來工作量非常巨大议双,切換成本非常高昂
3、無法覆蓋全部機(jī)型捉片,想覆蓋更多機(jī)型的做法就是生成更多的資源文件,但這樣會(huì)增加App體積汞舱,在沒有覆蓋的機(jī)型上還會(huì)出現(xiàn)一定的誤差伍纫,所以有時(shí)需要在適配效果和占用空間上做一些抉擇
4、不能自動(dòng)支持橫豎屏切換時(shí)的適配
5昂芜、不能以高度為基準(zhǔn)進(jìn)行適配莹规,考慮到這個(gè)方案的名字本身就叫最小寬度限定符適配方案
布局ConstraintLayout
一、較高的性能優(yōu)勢(shì):布局嵌套層次越高泌神,性能開銷越大良漱。而使用ConstraintLayout,經(jīng)常就一層嵌套就搞定了欢际,所以其性能要好很多母市。
二、屏幕適配:ConstraintLayout的大小损趋、距離都可以使用比例來設(shè)置患久,所以其適配性更好。
三、書寫簡(jiǎn)單
四蒋失、可視化編輯:ConstraintLayout也有十分方便完善的可視化編輯器返帕,不用寫xml也基本上能實(shí)現(xiàn)大部分功能。
match_parent:適配并不能代替match_parent篙挽,而只是為了更好的在不同屏幕上顯示效果圖
個(gè)人感想:
????????DPI的存在荆萤,不就是為了讓大屏能顯示更多的內(nèi)容,如果一個(gè)大屏手機(jī)和小屏手機(jī)铣卡,顯示的內(nèi)容都相同链韭,那用戶買大屏手機(jī)又有什么意義呢?每個(gè)機(jī)型每個(gè)版本的設(shè)備都適配完美算行,讓自己的?App體驗(yàn)更好梧油,哪怕付出更大的成本,有些時(shí)候想象是美好的州邢。
魚和熊掌不可兼得儡陨,只是取舍問題。(也可以結(jié)合smallestWidth適配方案實(shí)現(xiàn)在大屏上顯示應(yīng)有的比例)量淌。
xhdpi應(yīng)該是首選
xhdpi分辨率以內(nèi)的手機(jī)需求量最旺盛
? ?????目前市面上最普遍的高端機(jī)的分辨率還多集中在720X1080范圍內(nèi)(xhdpi)骗村,所以目前來看xhpdi規(guī)格的圖片資源成為了首選
節(jié)省設(shè)計(jì)資源&工作量
????????在現(xiàn)在的App開發(fā)中(iOS和Android版本),有些設(shè)計(jì)師為了保持App不同版本的體驗(yàn)交互一致呀枢,可能會(huì)以iPhone手機(jī)為基礎(chǔ)進(jìn)行設(shè)計(jì)胚股,包括后期的切圖之類的。設(shè)計(jì)師們一般都會(huì)用iPhone6和iPhone7(6s和7s的尺寸以及分辨率都一樣)來做原型設(shè)計(jì)裙秋,所有參數(shù)請(qǐng)看下圖
?iPhone主流的屏幕dpi約等于320, 剛好屬于xhdpi琅拌,所以選擇xhdpi作為唯一一套dpi圖片資源,可以讓設(shè)計(jì)師不用專門為Android端切圖摘刑,直接把iPhone的那一套切好的圖片資源放入drawable-xhdpi文件夾里就好进宝,這樣大大減少的設(shè)計(jì)師的工作量!