Android 屏幕適配終結者

背景

以前基於頭條的適配方案寫了篇文章 Android 屏幕適配從未如斯簡單,但後續發現仍是有挺多坑的,這些坑都記錄在了 GitHub 屏幕適配問題彙總及解決,基於這麼多坑,最終我發現了一種更完美的適配方案,本打算一個多月前就寫這篇文章的,但因爲公司事務繁忙一直抽不出空來,拖更到如今才發佈,下面就讓我來分享下此法,先來吹下優勢吧。java

優勢

1. 無侵入性

首先科普下 Android 中的一個長度單位:pt,它表示一個點,是屏幕的物理尺寸,其大小爲 1 英寸的 1 / 72,也就是 72pt 等於 1 英寸(其實 Android 中還有比較少見的 inmm 的長度單位)。而我本次的適配使用的單位剛好是 pt,因此對你從前使用的佈局不會形成任何影響,在老項目中開發新功能你能夠膽大地加入該適配方案,新項目的話更能夠堅決果斷地採用該適配,而且在關閉該關閉後,pt 效果等同於 dp 哦。git

2. 靈活性高

若是你想要對某個 View 作到不一樣分辨率的設備下,使其尺寸在適配維度上所佔比例一致的話,那麼對它使用 pt 單位便可,若是你不想要這樣的效果,而是想要更大尺寸的設備顯示更多的內容,那麼你能夠像從前那樣寫 dpsp 什麼的便可,結合這兩點,在界面佈局上你就能夠遊刃有餘地作到你想要的效果。github

3. 不會影響系統 View 和三方 View 的大小

這點其實在無侵入性中已經表現出來了,因爲頭條的方案是直接修改 DisplayMetrics#densitydp 適配,這樣會致使系統 View 尺寸和原先不一致,好比 DialogToast、 尺寸,一樣,三方 View 的大小也會和原先效果不一致,這也就是我選擇 pt 適配的緣由之一。bash

4. 不會失效

這一點是最值得吹牛的,由於不論頭條的適配仍是 AndroidAutoSize,都會存在 DisplayMetrics#density 被還原的狀況,須要本身從新設置回去,最顯著的就是界面中存在 WebView 的話,因爲其初始化的時候會還原 DisplayMetrics#density 的值致使適配失效,固然這點已經有解決方案了,但還會有不少其餘狀況會還原 DisplayMetrics#density 的值致使適配失效。而我這方案就是爲了解決這個痛點,不讓 DisplayMetrics 中的值被還原致使適配失效。ide

效果

說了這麼多,先上下效果圖壓壓驚吧,每種分辨率的圖依次是寬度 1080pt 適配,高度 1920pt 適配以及關閉適配的效果。函數

480 x 800 - mdpi(160dpi)

mdpi

720 x 1280 - xhdpi(320dpi)

xhdpi

1080 x 1920 - xxhdpi(480dpi)

xxhdpi

1440x2560 - 560dpi

560dpi

能夠看到效果圖中 WebView 對以後的 View 並無產生適配失效的問題,這是以前適配所不能解決的問題。組件化

如何建立預覽?

在 AS 中 Tools -> AVD Manager -> Create Virtual Device...,咱們以適配 1080 x 1920px 爲例,具體操做以下:佈局

1080pt

建立完設備咱們在預覽界面選中這個設備便可看到 pt 單位效果。spa

設計師給你的設計圖尺寸是多少,那你就建多少尺寸的設備便可,好比是 720 x 1280px 的,那你把上圖的尺寸換成 7201280,再計算下屏幕尺寸便可,若是是 360 x 640dp 的話,那就把上圖的尺寸換成 360640,再計算下屏幕尺寸便可,不用去 care 單位究竟是什麼,設計圖標註多少那你就寫多少便可,無需換算。適配的時候傳入這個緯度的尺寸值便可,好比 720 x 1280 的寬度適配,那就傳入 720 便可。設計

原理及用法

原理其實也是基於頭條的原理,不過我是操做 pt,因此不是改 DisplayMetrics#density,而是 DisplayMetrics#xdpi,因爲適配不會失效,因此須要在適配的 Activity 中重寫下 getResources() 函數,由於每次 View 在變動尺寸時都會調用到 getResources(),因此咱們直接在這裏進行適配就不會致使失效,效果圖中對應的代碼分別以下所示:

override fun getResources(): Resources {
    return AdaptScreenUtils.adaptWidth(super.getResources(), 1080)
}

override fun getResources(): Resources {
    return AdaptScreenUtils.adaptHeight(super.getResources(), 1920)
}

override fun getResources(): Resources {
    return AdaptScreenUtils.closeAdapt(super.getResources())
}
複製代碼

其源碼、Demo 以及 API 以下所示:

AdaptScreen 相關 -> [AdaptScreenUtils.java][adaptScreen.java] -> [Demo][adaptScreen.demo]

adaptWidth : 適配寬度
adaptHeight: 適配高度
closeAdapt : 關閉適配(pt 等同於 dp)
pt2Px      : pt 轉 px
px2Pt      : px 轉 pt
複製代碼

pt2Px 及 px2Pt 是提供給須要動態操做 View 的。

如上只需依賴 AndroidUtilCode 最新版本便可:

implementation 'com.blankj:utilcode:1.22.3'
複製代碼

結尾的話

看了原理以後是否是以爲很簡單,但能想到這種解決方案的又能有幾人呢,我也是站在了巨人的肩膀上才能想到這一層次,但願該適配方案能像文章標題同樣終結咱們的適配,這是我目前發現最簡單有效的適配方案,若是以爲不錯的話記得推薦給身邊的 Androider 哦,使用過程有問題的話歡迎同步到 「Android 屏幕適配終結者」問題彙總 這個 issue 中。

最後再插個內容,AndroidUtilCode 項目已改造爲組件化,有興趣的能夠翻閱源碼查看,相信你確定會學到很多好東西的,下一篇文章我會爲你們介紹下這方面的內容,期待我能儘快出產吧。

相關文章
相關標籤/搜索