Android 屏幕適配終結(jié)者

背景

之前基于頭條的適配方案寫(xiě)了篇文章 Android 屏幕適配從未如斯簡(jiǎn)單,但后續(xù)發(fā)現(xiàn)還是有挺多坑的,這些坑都記錄在了 GitHub 屏幕適配問(wèn)題匯總及解決,基于這么多坑,最終我發(fā)現(xiàn)了一種更完美的適配方案,本打算一個(gè)多月前就寫(xiě)這篇文章的,但由于公司事務(wù)繁忙一直抽不出空來(lái),拖更到現(xiàn)在才發(fā)布,下面就讓我來(lái)分享下此法,先來(lái)吹下優(yōu)點(diǎn)吧。

優(yōu)點(diǎn)

1. 無(wú)侵入性

首先科普下 Android 中的一個(gè)長(zhǎng)度單位:pt,它表示一個(gè)點(diǎn),是屏幕的物理尺寸,其大小為 1 英寸的 1 / 72,也就是 72pt 等于 1 英寸(其實(shí) Android 中還有比較少見(jiàn)的 inmm 的長(zhǎng)度單位)。而我本次的適配使用的單位恰好是 pt,所以對(duì)你從前使用的布局不會(huì)造成任何影響,在老項(xiàng)目中開(kāi)發(fā)新功能你可以膽大地加入該適配方案,新項(xiàng)目的話(huà)更可以毫不猶豫地采用該適配,并且在關(guān)閉該關(guān)閉后,pt 效果等同于 dp 哦。

2. 靈活性高

如果你想要對(duì)某個(gè) View 做到不同分辨率的設(shè)備下,使其尺寸在適配維度上所占比例一致的話(huà),那么對(duì)它使用 pt 單位即可,如果你不想要這樣的效果,而是想要更大尺寸的設(shè)備顯示更多的內(nèi)容,那么你可以像從前那樣寫(xiě) dp、sp 什么的即可,結(jié)合這兩點(diǎn),在界面布局上你就可以游刃有余地做到你想要的效果。

3. 不會(huì)影響系統(tǒng) View 和三方 View 的大小

這點(diǎn)其實(shí)在無(wú)侵入性中已經(jīng)表現(xiàn)出來(lái)了,由于頭條的方案是直接修改 DisplayMetrics#densitydp 適配,這樣會(huì)導(dǎo)致系統(tǒng) View 尺寸和原先不一致,比如 DialogToast、 尺寸,同樣,三方 View 的大小也會(huì)和原先效果不一致,這也就是我選擇 pt 適配的原因之一。

4. 不會(huì)失效

這一點(diǎn)是最值得吹牛的,因?yàn)椴徽擃^條的適配還是 AndroidAutoSize,都會(huì)存在 DisplayMetrics#density 被還原的情況,需要自己重新設(shè)置回去,最顯著的就是界面中存在 WebView 的話(huà),由于其初始化的時(shí)候會(huì)還原 DisplayMetrics#density 的值導(dǎo)致適配失效,當(dāng)然這點(diǎn)已經(jīng)有解決方案了,但還會(huì)有很多其他情況會(huì)還原 DisplayMetrics#density 的值導(dǎo)致適配失效。而我這方案就是為了解決這個(gè)痛點(diǎn),不讓 DisplayMetrics 中的值被還原導(dǎo)致適配失效。

效果

說(shuō)了這么多,先上下效果圖壓壓驚吧,每種分辨率的圖依次是寬度 1080pt 適配,高度 1920pt 適配以及關(guān)閉適配的效果。

480 x 800 - mdpi(160dpi)

mdpi

720 x 1280 - xhdpi(320dpi)

xhdpi

1080 x 1920 - xxhdpi(480dpi)

xxhdpi

1440x2560 - 560dpi

560dpi

可以看到效果圖中 WebView 對(duì)之后的 View 并沒(méi)有產(chǎn)生適配失效的問(wèn)題,這是之前適配所不能解決的問(wèn)題。

如何創(chuàng)建預(yù)覽?

在 AS 中 Tools -> AVD Manager -> Create Virtual Device...,我們以適配 1080 x 1920px 為例,具體操作如下:

1080pt

創(chuàng)建完設(shè)備我們?cè)陬A(yù)覽界面選中這個(gè)設(shè)備即可看到 pt 單位效果。

設(shè)計(jì)師給你的設(shè)計(jì)圖尺寸是多少,那你就建多少尺寸的設(shè)備即可,比如是 720 x 1280px 的,那你把上圖的尺寸換成 7201280,再計(jì)算下屏幕尺寸即可,如果是 360 x 640dp 的話(huà),那就把上圖的尺寸換成 360640,再計(jì)算下屏幕尺寸即可,不用去 care 單位到底是什么,設(shè)計(jì)圖標(biāo)注多少那你就寫(xiě)多少即可,無(wú)需換算。適配的時(shí)候傳入這個(gè)維度的尺寸值即可,比如 720 x 1280 的寬度適配,那就傳入 720 即可。

原理及用法

原理其實(shí)也是基于頭條的原理,不過(guò)我是操作 pt,所以不是改 DisplayMetrics#density,而是 DisplayMetrics#xdpi,由于適配不會(huì)失效,所以需要在適配的 Activity 中重寫(xiě)下 getResources() 函數(shù),因?yàn)槊看?View 在變更尺寸時(shí)都會(huì)調(diào)用到 getResources(),所以我們直接在這里進(jìn)行適配就不會(huì)導(dǎo)致失效,效果圖中對(duì)應(yīng)的代碼分別如下所示:

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 相關(guān) -> [AdaptScreenUtils.java][adaptScreen.java] -> [Demo][adaptScreen.demo]

adaptWidth : 適配寬度
adaptHeight: 適配高度
closeAdapt : 關(guān)閉適配(pt 等同于 dp)
pt2Px      : pt 轉(zhuǎn) px
px2Pt      : px 轉(zhuǎn) pt

pt2Px 及 px2Pt 是提供給需要?jiǎng)討B(tài)操作 View 的。

如上只需依賴(lài) AndroidUtilCode 最新版本即可:

implementation 'com.blankj:utilcode:1.22.3'

結(jié)尾的話(huà)

看了原理之后是不是覺(jué)得很簡(jiǎn)單,但能想到這種解決方案的又能有幾人呢,我也是站在了巨人的肩膀上才能想到這一層次,希望該適配方案能像文章標(biāo)題一樣終結(jié)我們的適配,這是我目前發(fā)現(xiàn)最簡(jiǎn)單有效的適配方案,如果覺(jué)得不錯(cuò)的話(huà)記得推薦給身邊的 Androider 哦,使用過(guò)程有問(wèn)題的話(huà)歡迎同步到 「Android 屏幕適配終結(jié)者」問(wèn)題匯總 這個(gè) issue 中。

最后再插個(gè)內(nèi)容,AndroidUtilCode 項(xiàng)目已改造為組件化,有興趣的可以翻閱源碼查看,相信你肯定會(huì)學(xué)到不少好東西的,下一篇文章我會(huì)為大家介紹下這方面的內(nèi)容,期待我能盡快出產(chǎn)吧。

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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