原因
無論你要出去面試,還是身爲一個移動開發工程師。屏幕適配是客戶端最經常碰到的問題,因此掌握客戶端的屏幕適配是一個基本能力,優雅的屏幕適配,可以保證你還原設計稿的同時,還可以節約你的開發成本,該方案最終 5 行代碼就可以實現屏幕適配。
前置工作
來自備不同分辨率的機型2種:
機型A:720*1280 320dpi 5.5英寸(pixel 2)
機型B:1080*1920 420dpi 5.0英寸
產生的問題
首先我們先計算鋪滿機型A的寬度是多少dp?
因爲:計算公式px = dp * (dpi / 160)
又因爲:機型A寬度是720PX,機型A的dpi是320dpi。
所以:dp = px/(dpi/160) = 720/(320/160) = 360dp
結論:我們鋪滿一個機型A需要360dp。
最後佈局如下:
機型A上的展示:
機型B上的展示:
上述結論
同樣的一個TextView,寬度爲360dp,在機型A上是鋪滿的。在機型B上卻是留有空白。因此,在開發過程中,爲了還原設計稿的樣式,我們就需要統一的方案來進行適配。當設計師設計一套樣式的時候,至少保證所有的設計稿,在寬度的百分比上是一致的。
解決
1.Android官方方案
在res下面創建多套dimens.xml 文件如下:
結論:非常不優雅,而且工作量特別大,設計稿只有一套,你要自己想辦法拿到其他分辨率的設計稿寬高,而且會讓適配工作沒法收斂。
2.修改density進行Android的屏幕適配方案
首先我們要懂一點,無論是我們 Android 用 dp,pt,sp 還是其他,最後系統代碼都會通過 density 把他們轉換成px展示在屏幕上。
因爲我們在每個 View 的寬度,高度等都是填入 dp 值,那我們只要保證每個機型的屏幕總 dp 寬度不變,就能保證每個 View 在所有分辨率的屏幕上與屏幕的比例都保持不變,從而完成等比例適配,並且這個屏幕總 dp 寬度如果還能保證和設計圖的寬度一致的話,那我們在佈局時就可以直接按照設計圖上的尺寸填寫 dp 值。
dp = px/density
在這個公式中我們要保證屏幕的總 dp 寬度 和 設計圖總寬度一致,且在所有分辨率的屏幕上都保持不變,我們需要怎麼做呢?屏幕的總 px 寬度 每個機型都不一致,這個值是肯定會變化的,因此我們再用一下上述公式:
因爲:dp = px/density
所以:density = px/dp
又因爲:我們把設計圖的寬度等於手機的寬度
所以:density = 機型屏幕總寬度(px)/ 設計圖總寬度(dp)
驗證
回到開頭的問題,假設機型機型A的寬度就是設計圖總寬度爲 360 dp,那我們這時候帶入公式去驗證機型B?
一個 TextView 在這個設計圖上的尺寸是 360dp * 120dp,這個 View 的寬度佔整個機型A寬度是100%。
機型B,屏幕總寬度爲 1080 px,根據公式求出 density = 機型屏幕總寬度(px)/ 設計圖總寬度(dp) = 1080 / 360 = 3
這個 360dp * 120dp 的 TextView,系統最後會將高寬都換算成 px = dp * density = 360dp * 3 = 1080 px ,通過該方案也鋪滿了機型B。
代碼
採用kotlin實現的代碼
結果
機型A:
機型B:
因此,我們通過該方案,實現了屏幕適配。
優點
1、使用成本特別低,操作相當簡單,使用該方案後在頁面佈局時不需要額外的代碼和操作。
2、侵入性非常低,該方案和項目完全解耦,在項目佈局時不會依賴哪怕一行該方案的代碼,而且還是 Android 官方的 API,意味着當你遇到什麼問題無法解決,想切換爲其他屏幕適配方案時,基本不需要更改之前的代碼,整個切換過程幾乎在瞬間完成,會少很多麻煩,節約很多時間,試錯成本接近於 0,不會有任何性能的損耗。
3、可適配三方庫的控件和系統的控件(不止是 Activity 和 Fragment,Dialog、Toast 等所有系統控件都可以適配),由於修改的 density 在整個項目中是全局的,所以只要一次修改,項目中的所有地方都會受益。
缺點
1、只需要修改一次 density,項目中的所有地方都會自動適配,這個看似解放了雙手,減少了很多操作,但是實際上反應了一個缺點,那就是隻能一刀切的將整個項目進行適配,但適配範圍是不可控的。
2、這樣不是很好嗎?這樣本來是很好的,但是應用到這個方案是就不好了,因爲我上面的原理也分析了,這個方案依賴於設計圖尺寸,但是項目中的系統控件、三方庫控件、等非我們項目自身設計的控件,它們的設計圖尺寸並不會和我們項目自身的設計圖尺寸一樣。
3、當這個適配方案不分類型,將所有控件都強行使用我們項目自身的設計圖尺寸進行適配時,這時就會出現問題,當某個系統控件或三方庫控件的設計圖尺寸和和我們項目自身的設計圖尺寸差距非常大時,這個問題就越嚴重。
demo 地址,歡迎點star:https://github.com/YuriyPikachu/AutoSizeDemo
瞭解更多,歡迎關注:
- 博客:https://YuriyPikachu.github.io
- github:https://github.com/YuriyPikachu
- QQ技術交流羣:389274438
- csdn:https://blog.csdn.net/pjingying
- 知乎:YuriyPikachu
- 簡書:YuriyPikachu
- 郵箱:[email protected]
- 頭條:Android開發加油站
- 公衆號:Android開發加油站