1.簡介
??在Android開發(fā)中炒考,由于Android碎片化嚴重,屏幕分辨率千奇百怪,而想要在各種分辨率的設備上顯示基本一致的效果藕赞,適配成本越來越高。雖然Android官方提供了dp單位來適配卖局,但其在各種奇怪分辨率下表現(xiàn)卻不盡如人意斧蜕,因此下面探索一種簡單且低侵入的適配方式。
2.了解一下之間的關系
先來了解下px砚偶,dp惩激,dpi,density之間的關系
1.px(pixel 像素):就是屏幕上實際的像素點單位蟹演,一般HVGA代表320x480像素风钻。
2.dp / dip:設備獨立像素,android layout經(jīng)常使用的尺寸單位酒请,與設備屏幕有關骡技,dp是虛擬像素,在不同的像素密度的設備上會自動適配羞反。即與像素密度無關布朦。而dpi是根據(jù)屏幕真實的分辨率和尺寸來計算的,每個設備都可能不一樣的昼窗。
系統(tǒng)屏幕密度
ldpi文件夾下對應的密度為120dpi,對應的分辨率為240 * 320
mdpi文件夾下對應的密度為160dpi,對應的分辨率為320 * 480
hdpi文件夾下對應的密度為240dpi,對應的分辨率為480 * 800
xhdpi文件夾下對應的密度為320dpi,對應的分辨率為720 * 1280
xxhdpi文件夾下對應的密度為480dpi,對應的分辨率為1080 * 1920
android系統(tǒng)將密度為160dpi的屏幕作為標準對于mdpi文件夾是趴,在此屏幕的手機上1dp=1px。從上面系統(tǒng)屏幕密度可以得出各個密度值之間的換算澄惊;
mdpi中1dp=1px,
hdpi中1dp=1.5px
xhdpi中1dp=2px
xxhpi中1dp=3px
3.density:指的是1dp占當前屏幕的像素唆途。 density = DPI / 160
2.1.屏幕尺寸、分辨率掸驱、像素密度三者關系
通常情況下肛搬,一部手機的分辨率是寬x高,屏幕大小是以寸為單位毕贼,那么三者的關系是:
舉個例子:屏幕分辨率為:1920*1080温赔,屏幕尺寸為5吋的話,那么dpi為440鬼癣。
主要講講現(xiàn)在最主流的兩種屏幕適配方案陶贼,今日頭條適配方案 和 smallestWidth 限定符適配方案
建議大家不清楚這兩個方案的先看看這兩篇文章啤贩,才清楚我在講什么,后面我要講解它們的原理拜秧,以及驗證這兩種方案是否真的可行瓜晤,最后對他們進行深入對比,對于他們的一些缺點給予對應的解決方案腹纳,絕對干貨痢掠。
適配方案:
1.今日頭條適配方案
原理:適配方案的核心原理在于,根據(jù)以下公式算出 density
當前設備屏幕總寬度(單位為像素)/ 設計圖總寬度(單位為 dp) = density
density 的意思就是 1 dp 占當前設備多少像素
為什么要算出density嘲恍,這和屏幕適配有什么關系呢足画?
我們都知道,在我們布局文件中填寫的是什么單位佃牛,最終都會被轉化為px淹辞,所以我們常用px轉化dp的公式。
公式:dp = px / density
???density = dpi / 160
density 在每個設備上都是固定的俘侠,屏幕的總(px)寬度 / density = 屏幕的總(dp)寬度
例如:
?設備 1象缀,屏幕寬度為 1080px,480DPI爷速,屏幕總 dp 寬度為 1080 / (480 / 160) = 360dp
?設備 2央星,屏幕寬度為 1440px,560DPI惫东,屏幕總 dp 寬度為 1440 / (560 / 160) = 411dp
可以看到屏幕的總 dp 寬度在不同的設備上是會變化的莉给,但是我們在布局中填寫的 dp 值卻是固定不變的
這會導致什么呢?假設我們布局中有一個 View 的寬度為 100dp
在設備 1 中 該 View 的寬度占整個屏幕寬度的 27.8% (100 / 360 = 0.278)
在設備 2 中該 View 的寬度就只能占整個屏幕寬度的 24.3% (100 / 411 = 0.243)
可以看到這個 View 在像素越高的屏幕上廉沮,dp 值雖然沒變颓遏,但是與屏幕的實際比例卻發(fā)生了較大的變化,所以肉眼的觀看效果滞时,會越來越小叁幢,這就導致了傳統(tǒng)的填寫 dp 的屏幕適配方式產(chǎn)生了較大的誤差。
這時我們要想完美適配坪稽,那就必須保證這個 View 在任何分辨率的屏幕上曼玩,與屏幕的比例都是相同的
這時我們該怎么做呢?改變每個 View 的 dp 值刽漂?不現(xiàn)實演训,在每個設備上都要通過代碼動態(tài)計算 View 的 dp 值弟孟,工作量太大
如果每個 View 的 dp 值是固定不變的贝咙,那我們只要保證每個設備的屏幕總 dp 寬度不變,就能保證每個 View 在所有分辨率的屏幕上與屏幕的比例都保持不變拂募,從而完成等比例適配庭猩,并且這個屏幕總 dp 寬度如果還能保證和設計圖的寬度一致的話窟她,那我們在布局時就可以直接按照設計圖上的尺寸填寫 dp 值
屏幕的總 px 寬度 / density = 屏幕的總 dp 寬度
在這個公式中我們要保證 屏幕的總 dp 寬度 和 設計圖總寬度 一致,并且在所有分辨率的屏幕上都保持不變蔼水,我們需要怎么做呢震糖?屏幕的總 px 寬度 每個設備都不一致,這個值是肯定會變化的趴腋,這時今日頭條的公式就派上用場了
當前設備屏幕總寬度(單位為像素)/ 設計圖總寬度(單位為 dp) = density
這個公式就是把上面公式中的 屏幕的總 dp 寬度 換成 設計圖總寬度吊说,原理都是一樣的,只要 density 根據(jù)不同的設備進行實時計算并作出改變优炬,就能保證 設計圖總寬度 不變颁井,也就完成了適配
驗證設備 1
屏幕總寬度為 1080 px,根據(jù)今日頭條的的公式求出 density?1080(屏幕寬度px) / 375(設計圖總寬度dp) = 2.88 (density)
如果一個 50dp * 50dp 的 View蠢护,系統(tǒng)最后會將高寬都換算成 px雅宾,50dp * 2.88 = 144 px (根據(jù)公式 dp * density = px)
View 實際寬度與 屏幕總寬度 的比例 :144 / 1080 = 0.133
View 和設計圖中的比例: 50 / 375 = 0.133 ?所以完成了等比例縮放
某些設備總寬度為 1080 px,但是 DPI 可能不同葵硕,是否會對今日頭條適配方案產(chǎn)生影響眉抬?其實這個方案根本沒有根據(jù) DPI 求出 density,是根據(jù)自己的公式求出的 density懈凹,所以這對今日頭條的方案沒有影響
驗證設備 2
屏幕總寬度為 1440 px蜀变,根據(jù)今日頭條的的公式求出 density,1440(屏幕寬度px) / 375(設計圖總寬度dp) = 3.84 (density)
如果一個 50dp * 50dp 的 View介评,系統(tǒng)最后會將高寬都換算成 px昏苏,50dp * 3.84 = 192 px (根據(jù)公式 dp * density = px)
View 實際寬度與 屏幕總寬度 的比例 :192 / 1440 = 0.133
View 和設計圖中的比例: 50 / 375 = 0.133 ?所以完成了等比例縮放
兩個不同分辨率的設備都完成了等比例縮放,證明今日頭條屏幕適配方案在不同分辨率的設備上都是有效的威沫,如果大家還心存疑慮贤惯,可以再試試其他分辨率的設備,其實到最后得出的比例不會有任何偏差, 都是 0.133
地址:https://github.com/JessYanCoding/AndroidAutoSize
使用:
??添加:implementation 'me.jessyan:autosize:1.1.2'
??在我們在清單文件中配置
<manifest>
<application>
<meta-data
android:name="design_width_in_dp"
android:value="1080"/>
<meta-data
android:name="design_height_in_dp"
android:value="1920"/>
</application>
</manifest>
2.SmallestWidth限定符適配方案