今日頭條屏幕適配方案終極版正式發(fā)布!

原文地址: http://www.itdecent.cn/p/4aa23d69d481

以下是 騷年你的屏幕適配方式該升級(jí)了! 系列文章,歡迎轉(zhuǎn)發(fā)以及分享:

前言

我在前面兩篇文章中詳細(xì)介紹了 今日頭條適配方案SmallestWidth 限定符適配方案 的原理,并驗(yàn)證了它們的可行性,以及總結(jié)了它們各自的優(yōu)缺點(diǎn),可以說(shuō)這兩個(gè)方案都是目前比較優(yōu)秀、比較主流的 Android 屏幕適配方案,而且它們都已經(jīng)擁有了一定的用戶基數(shù)

但是對(duì)于一些才接觸這兩個(gè)方案的朋友,肯定或多或少還是不知道如何選擇這兩個(gè)方案,我雖然在之前的文章中給出了它們各自的優(yōu)缺點(diǎn),但是并沒(méi)有用統(tǒng)一的標(biāo)準(zhǔn)對(duì)它們進(jìn)行更細(xì)致的對(duì)比,所以也就沒(méi)辦法更形象的體現(xiàn)它們的優(yōu)劣,那下面我就用統(tǒng)一的標(biāo)準(zhǔn)對(duì)它們進(jìn)行對(duì)比,看看它們的對(duì)比情況

方案對(duì)比

我始終堅(jiān)定地認(rèn)為在這兩個(gè)方案中,并不能以單個(gè)標(biāo)準(zhǔn)就能評(píng)判出誰(shuí)一定比誰(shuí)好,因?yàn)樗鼈兌加懈髯缘膬?yōu)缺點(diǎn),都不是完美的,從更客觀的角度來(lái)看,它們誰(shuí)都不能成為最好的那個(gè),只有可能明確了它們各自的優(yōu)缺點(diǎn),知道在它們的優(yōu)缺點(diǎn)里什么是我能接受的,什么是我不能接受的,是否能為了某些優(yōu)點(diǎn)做出某些妥協(xié),從而選擇出一個(gè)最適合自己項(xiàng)目的屏幕適配方案

單純的爭(zhēng)論誰(shuí)是最好的 Android 屏幕適配方案沒(méi)有任何意義,每個(gè)人的需求不一樣,站的角度不一樣,評(píng)判標(biāo)準(zhǔn)也不一樣,你能接受的東西他不一定能接受,你覺(jué)得不可接受的東西他卻覺(jué)得可以接受,你有你的理由,他有他的理由,想讓一個(gè)觀點(diǎn)讓所有人都能接受太難了!所以我在這里只是列出它們的對(duì)比項(xiàng)和對(duì)比結(jié)果,盡可能的做到客觀,最后的選擇結(jié)果請(qǐng)自行決定,如果還有什么遺漏的對(duì)比項(xiàng),請(qǐng)補(bǔ)充!

對(duì)比項(xiàng)目 對(duì)比對(duì)象 A 對(duì)比結(jié)果 對(duì)比對(duì)象 B
適配效果(越高越好) 今日頭條適配方案 SW 限定符適配方案(在未覆蓋的機(jī)型上會(huì)存在一定的誤差)
穩(wěn)定性(越高越好) 今日頭條適配方案 < SW 限定符適配方案
靈活性(越高越好) 今日頭條適配方案 > SW 限定符適配方案
擴(kuò)展性(越高越好) 今日頭條適配方案 > SW 限定符適配方案
侵入性(越低越好) 今日頭條適配方案 < SW 限定符適配方案
使用成本(越低越好) 今日頭條適配方案 < SW 限定符適配方案
維護(hù)成本(越低越好) 今日頭條適配方案 < SW 限定符適配方案
性能損耗 今日頭條適配方案沒(méi)有性能損耗 = SW 限定符適配方案沒(méi)有性能損耗
副作用 今日頭條適配方案會(huì)影響一些三方庫(kù)和系統(tǒng)控件 SW 限定符適配方案會(huì)影響 App 的體積

可以看到 SmallestWidth 限定符適配方案今日頭條適配方案 的適配效果其實(shí)都是差不多的,我在前面的文章中也通過(guò)公式計(jì)算過(guò)它們的精確度,SmallestWidth 限定符適配方案 運(yùn)行在未覆蓋的機(jī)型上雖然也可以適配,但是卻會(huì)出現(xiàn)一定的誤差,所以 今日頭條適配方案 的適配精確度確實(shí)要比 SmallestWidth 限定符適配方案 略高的,不過(guò)只要 SmallestWidth 限定符適配方案 合理的分配資源文件,適配效果的差距應(yīng)該也不大

SmallestWidth 限定符適配方案 主打的是穩(wěn)定性,在運(yùn)行過(guò)程中極少會(huì)出現(xiàn)安全隱患,適配范圍也可控,不會(huì)產(chǎn)生其他未知的影響,而 今日頭條適配方案 主打的是降低開(kāi)發(fā)成本、提高開(kāi)發(fā)效率,使用上更靈活,也能滿足更多的擴(kuò)展需求,簡(jiǎn)單一句話概括就是,這兩兄弟,一個(gè)求穩(wěn),一個(gè)求快,好了,我就介紹這么多了,自己選擇吧!

AndroidAutoSize

AndroidAutoSize

由來(lái)

下面就開(kāi)始介紹我根據(jù) 今日頭條屏幕適配方案 優(yōu)化的屏幕適配框架 AndroidAutoSize,大家千萬(wàn)不要認(rèn)為,我推出的屏幕適配框架 AndroidAutoSize 是根據(jù) 今日頭條屏幕適配方案 優(yōu)化的,我本人就一定支持 今日頭條屏幕適配方案 是最好的 Android 屏幕適配方案這個(gè)觀點(diǎn),它確實(shí)很優(yōu)秀,但同樣也有很多不足,我最真實(shí)的觀點(diǎn)在上面就已經(jīng)表述咯,至于我為什么要根據(jù) 今日頭條屏幕適配方案 再封裝一個(gè)屏幕適配框架,無(wú)外乎就以下幾點(diǎn)原因:

  • SmallestWidth 限定符適配方案 已經(jīng)有多個(gè)優(yōu)秀的開(kāi)源解決方案了,它們已經(jīng)能滿足我們?nèi)粘i_(kāi)發(fā)中的所有需求

  • 今日頭條 官方技術(shù)團(tuán)隊(duì)只公布了 今日頭條屏幕適配方案文章 以及核心代碼,但并沒(méi)有在 Github 上創(chuàng)建公開(kāi)的倉(cāng)庫(kù),一個(gè)新的方案必定要有一個(gè)成長(zhǎng)迭代的過(guò)程,在此期間,一定需要一個(gè)可以把所有使用者聚集起來(lái)的公共社區(qū),可以讓所有使用該方案的使用者在上面交流,大家一起總結(jié)、一起填坑,這樣才能讓該方案更成熟穩(wěn)定,這就是開(kāi)源的力量

  • 今日頭條 官方技術(shù)團(tuán)隊(duì)公布的核心代碼并不能滿足我的所有需求,已經(jīng)開(kāi)源的其他基于 今日頭條屏幕適配方案 的開(kāi)源項(xiàng)目以及解決方案也不能滿足我的所有需求,而我有更好的實(shí)現(xiàn)想法

  • MVPArms 需要一個(gè)適配效果還不錯(cuò)并且切換維護(hù)成本也比較低的屏幕適配框架,以幫助使用者用較低的成本、工作量將已經(jīng)停止維護(hù)的 AndroidAutoLayout 快速替換掉

我建議大家都可以去實(shí)際體驗(yàn)一下 今日頭條屏幕適配方案SmallestWidth 限定符適配方案,感受下它們的異同,我給的建議是,可以在項(xiàng)目中先使用 今日頭條屏幕適配方案,感受下它的使用方式以及適配效果,今日頭條屏幕適配方案 的侵入性非常低,如果在使用過(guò)程中遇到什么不能解決的問(wèn)題,馬上可以切換為其他的屏幕適配方案,在切換的過(guò)程中也花費(fèi)不了多少工作量,試錯(cuò)成本非常低

但如果你在項(xiàng)目中先使用 SmallestWidth 限定符適配方案,之后在使用的過(guò)程中再遇到什么不能解決的問(wèn)題,這時(shí)想切換為其他的屏幕適配方案,這工作量可就大了,每個(gè) Layout 文件都含有大量的 dimens 引用,改起來(lái)這工作量得有多大,想想都覺(jué)得后怕,這就是侵入性太高導(dǎo)致的最致命的問(wèn)題

如果想體驗(yàn) 今日頭條屏幕適配方案,千萬(wàn)不要錯(cuò)過(guò) AndroidAutoSize 哦!僅需一步即可接入項(xiàng)目,下面是 AndroidAutoSize 的地址:

Github : 您的 Star 是我堅(jiān)持的動(dòng)力 ?

與今日頭條屏幕適配方案的關(guān)系

AndroidAutoSize今日頭條屏幕適配方案 的關(guān)系,相當(dāng)于汽車和發(fā)動(dòng)機(jī)的關(guān)系,今日頭條屏幕適配方案 官方公布的代碼,只實(shí)現(xiàn)了修改系統(tǒng) density 的相關(guān)邏輯,這的確在屏幕適配中起到了最關(guān)鍵的作用,但這還遠(yuǎn)遠(yuǎn)還不夠

要想讓使用者能夠更傻瓜式的使用該方案,并且能夠應(yīng)對(duì)日常開(kāi)發(fā)中的所有復(fù)雜需求,那在架構(gòu)框架時(shí),還需要考慮 API 的易用性以及合理性、框架的擴(kuò)展性以及靈活性、功能的全面性、注釋和文檔的易讀性等多個(gè)方面的問(wèn)題

于是我?guī)е业倪@些標(biāo)準(zhǔn)在網(wǎng)上搜尋了很久,發(fā)現(xiàn)并沒(méi)有任何一個(gè)開(kāi)源框架或解決方案能夠達(dá)到我的所有標(biāo)準(zhǔn),它們大多數(shù)還只是停留在將 今日頭條屏幕適配方案 封裝成工具類來(lái)引入項(xiàng)目的階段,這樣在功能的擴(kuò)展上有限制,并且對(duì)用戶的使用體驗(yàn)也不好,而我想做的是一個(gè)全面性的產(chǎn)品級(jí)屏幕適配框架,這離我最初的構(gòu)想,差距還非常大,于是我只好自己動(dòng)手,將我的所有思想實(shí)現(xiàn),這才有了 AndroidAutoSize

寫(xiě)完 AndroidAutoSize 框架后,因?yàn)閷?duì) 今日頭條屏幕適配方案 有了更加深入的理解,所以才寫(xiě)了 騷年你的屏幕適配方式該升級(jí)了!(一)-今日頭條適配方案,以幫助大家更清晰的理解 今日頭條屏幕適配方案

與 AndroidAutoLayout 的關(guān)系

AndroidAutoSize 因?yàn)槊趾?鴻神AndroidAutoLayout 非常相似,并且在填寫(xiě)設(shè)計(jì)圖尺寸的方式上也極為相似,再加上我寫(xiě)的屏幕適配系列的文章也發(fā)布在了 鴻神 的公眾號(hào)上,所以很多人以為 AndroidAutoSize鴻神 寫(xiě)的 AndroidAutoLayout 的升級(jí)版,這里我哭笑不得 ??,我只好在這里說(shuō)一句,大家好,我叫 JessYan,的確可以理解為 AndroidAutoSizeAndroidAutoLayout 的升級(jí)版,但是它是我寫(xiě)的,關(guān)注一波唄

AndroidAutoSizeAndroidAutoLayout 的原理,卻天差地別,比如 AndroidAutoLayout 只能使用 px 作為布局單位,而 AndroidAutoSize 恰好相反,在布局中 dp、sp、pt、in、mm 所有的單位都能支持,唯獨(dú)不支持 px,但這也意味著 AndroidAutoSizeAndroidAutoLayout 在項(xiàng)目中可以共存,互不影響,所以使用 AndroidAutoLayout 的老項(xiàng)目也可以放心的引入 AndroidAutoSize,慢慢的完成屏幕適配框架的切換

之所以將框架取名為 AndroidAutoSize,第一,是想致敬 AndroidAutoLayout 對(duì) Android 屏幕適配領(lǐng)域的貢獻(xiàn),第二,也想成為在 Android 屏幕適配領(lǐng)域有重要影響力的框架

結(jié)構(gòu)

我在上面就已經(jīng)說(shuō)了很多開(kāi)源框架以及解決方案,只是把 今日頭條屏幕適配方案 簡(jiǎn)單的封裝成一個(gè)工具類然后引入項(xiàng)目,這時(shí)很多人就會(huì)說(shuō)了 今日頭條屏幕適配方案 官方公布的全部代碼都只有 30 行不到,你不把它封裝成工具類,那封裝成什么?該怎么封裝?下面就來(lái)看看 AndroidAutoSize 的整體結(jié)構(gòu)

├── external
│   ├── ExternalAdaptInfo.java
│   ├── ExternalAdaptManager.java
│── internal
│   ├── CancelAdapt.java
│   ├── CustomAdapt.java
│── unit
│   ├── Subunits.java
│   ├── UnitsManager.java
│── utils
│   ├── AutoSizeUtils.java
│   ├── LogUtils.java
│   ├── Preconditions.java
│   ├── ScreenUtils.java
├── ActivityLifecycleCallbacksImpl.java
├── AutoAdaptStrategy.java
├── AutoSize.java
├── AutoSizeConfig.java
├── DefaultAutoAdaptStrategy.java
├── DisplayMetricsInfo.java
├── FragmentLifecycleCallbacksImpl.java
├── InitProvider.java

AndroidAutoSize 根據(jù) 今日頭條屏幕適配方案 官方公布的 30 行不到的代碼,經(jīng)過(guò)不斷的優(yōu)化和擴(kuò)展,發(fā)展成了現(xiàn)在擁有 18 個(gè)類文件,上千行代碼的全面性屏幕適配框架,在迭代的過(guò)程中完善和優(yōu)化了很多功能,相比 今日頭條屏幕適配方案 官方公布的原始代碼,AndroidAutoSize 更加穩(wěn)定、更加易用、更加強(qiáng)大,歡迎閱讀源碼,注釋非常詳細(xì)哦!

功能介紹

AndroidAutoSize 在使用上非常簡(jiǎn)單,只需要填寫(xiě)設(shè)計(jì)圖尺寸這一步即可接入項(xiàng)目,但需要注意的是,AndroidAutoSize 有兩種類型的布局單位可以選擇,一個(gè)是 主單位 (dp、sp),一個(gè)是 副單位 (pt、in、mm),兩種單位面向的應(yīng)用場(chǎng)景都有不同,也都有各自的優(yōu)缺點(diǎn)

  • 主單位: 使用 dp、sp 為單位進(jìn)行布局,侵入性最低,會(huì)影響其他三方庫(kù)頁(yè)面、三方庫(kù)控件以及系統(tǒng)控件的布局效果,但 AndroidAutoSize 也通過(guò)這個(gè)特性,使用 ExternalAdaptManager 實(shí)現(xiàn)了在不修改三方庫(kù)源碼的情況下適配三方庫(kù)的功能

  • 副單位: 使用 pt、in、mm 為單位進(jìn)行布局,侵入性高,對(duì)老項(xiàng)目的支持比較好,不會(huì)影響其他三方庫(kù)頁(yè)面、三方庫(kù)控件以及系統(tǒng)控件的布局效果,可以徹底的屏蔽修改 density 所造成的所有未知和已知問(wèn)題,但這樣 AndroidAutoSize 也就無(wú)法對(duì)三方庫(kù)進(jìn)行適配

大家可以根據(jù)自己的應(yīng)用場(chǎng)景在 主單位副單位 中選擇一個(gè)作為布局單位,建議想引入老項(xiàng)目并且注重穩(wěn)定性的人群使用 副單位,只是想試試本框架,隨時(shí)可能切換為其他屏幕適配方案的人群使用 主單位

其實(shí) AndroidAutoSize 可以同時(shí)支持 主單位副單位,但 AndroidAutoSize 可以同時(shí)支持 主單位副單位 的目的,只是為了讓使用者可以在 主單位副單位 之間靈活切換,因?yàn)榍袚Q單位的工作量可能非常巨大,不能立即完成,但領(lǐng)導(dǎo)又要求馬上打包上線,這時(shí)就可以起到一個(gè)很好的過(guò)渡作用

主單位

主單位Demodemo

基本使用

AndroidAutoSize 引入項(xiàng)目后,只要在 appAndroidManifest.xml 中填寫(xiě)上設(shè)計(jì)圖尺寸,無(wú)需其他過(guò)多配置 (如果你沒(méi)有其他自定義需求的話),AndroidAutoSize 即可自動(dòng)運(yùn)行,像下面這樣??

<manifest>
    <application>            
        <meta-data
            android:name="design_width_in_dp"
            android:value="360"/>
        <meta-data
            android:name="design_height_in_dp"
            android:value="640"/>           
     </application>           
</manifest>

在使用主單位時(shí),design_width_in_dpdesign_height_in_dp 的單位必須是 dp,如果設(shè)計(jì)師給你的設(shè)計(jì)圖,只標(biāo)注了 px 尺寸 (現(xiàn)在已經(jīng)有很多 UI 工具可以自動(dòng)標(biāo)注 dp 尺寸了),那請(qǐng)自行根據(jù)公式 dp = px / (DPI / 160)px 尺寸轉(zhuǎn)換為 dp 尺寸,如果你不知道 DPI 是多少?那請(qǐng)以自己測(cè)試機(jī)的 DPI 為準(zhǔn),如果連怎么得到設(shè)備的 DPI 都不知道?百度吧好伐,如果你實(shí)在找不到設(shè)備的 DPI 那就直接將 px 尺寸除以 3 或者 2 也是可以的

如果你只是想使用 AndroidAutoSize 的基礎(chǔ)功能,AndroidAutoSize 的使用方法在這里就結(jié)束了,只需要上面這一步,即可幫助你以最簡(jiǎn)單的方式接入 AndroidAutoSize,但是作為一個(gè)全面性的屏幕適配框架,在保證基礎(chǔ)功能的簡(jiǎn)易性的同時(shí),也必須保證復(fù)雜的需求也能在框架內(nèi)被解決,從而達(dá)到一個(gè)小閉環(huán),所以下面介紹的內(nèi)容全是前人踩坑踩出來(lái)的一些必備功能,如果你沒(méi)這個(gè)需求,或者覺(jué)得麻煩,可以按需查看或者跳過(guò),下面的內(nèi)容建議和 Demo 配合起來(lái)閱讀,效果更佳

注意事項(xiàng)

  • 你在 AndroidManifest.xml 中怎么把設(shè)計(jì)圖的 px 尺寸轉(zhuǎn)換為 dp 尺寸,那在布局時(shí),每個(gè)控件的大小也需要以同樣的方式將設(shè)計(jì)圖上標(biāo)注的 px 尺寸轉(zhuǎn)換為 dp 尺寸,千萬(wàn)不要在 AndroidManifest.xml 中填寫(xiě)的是 dp 尺寸,卻在布局中繼續(xù)填寫(xiě)設(shè)計(jì)圖上標(biāo)注的 px 尺寸
  • design_width_in_dpdesign_height_in_dp 雖然都需要填寫(xiě),但是 AndroidAutoSize 只會(huì)將高度和寬度其中的一個(gè)作為基準(zhǔn)進(jìn)行適配,一方作為基準(zhǔn),另一方就會(huì)變?yōu)閭溆茫J(rèn)以寬度為基準(zhǔn)進(jìn)行適配,可以通過(guò) AutoSizeConfig#setBaseOnWidth(Boolean) 不停的切換,這意味著最后運(yùn)行到設(shè)備上的布局效果,在高度和寬度中只有一方可以和設(shè)計(jì)圖上一模一樣,另外一方會(huì)和設(shè)計(jì)圖出現(xiàn)偏差,為什么不像 AndroidAutoLayout 一樣,高和寬都以設(shè)計(jì)圖的效果等比例完美呈現(xiàn)呢?這也很簡(jiǎn)單,你無(wú)法保證所有設(shè)備的高寬比例都和你設(shè)計(jì)圖上的高寬比例一致,特別是在現(xiàn)在全面屏全面推出的情況下,如果這里不這樣做的話,當(dāng)你的項(xiàng)目運(yùn)行在與設(shè)計(jì)圖高寬比例不一致的設(shè)備上時(shí),布局會(huì)出現(xiàn)嚴(yán)重的變形,這個(gè)幾率非常大,詳情請(qǐng)看 這里

自動(dòng)運(yùn)行是如何做到的?

很多人有疑惑,為什么使用者只需要在 AndroidManifest.xml 中填寫(xiě)一下 meta-data 標(biāo)簽,其他什么都不做,AndroidAutoSize 就能自動(dòng)運(yùn)行,并在 App 啟動(dòng)時(shí)自動(dòng)解析 AndroidManifest.xml 中填寫(xiě)的設(shè)計(jì)圖尺寸,這里很多人不敢相信,問(wèn)我真的只需要填寫(xiě)下設(shè)計(jì)圖尺寸框架就可以正常運(yùn)行嗎?難道使用了什么 黑科技?

其實(shí)這里并沒(méi)有用到什么 黑科技,原理反而非常簡(jiǎn)單,只需要聲明一個(gè) ContentProvider,在它的 onCreate 方法中啟動(dòng)框架即可,在 App 啟動(dòng)時(shí),系統(tǒng)會(huì)在 App 的主進(jìn)程中自動(dòng)實(shí)例化你聲明的這個(gè) ContentProvider,并調(diào)用它的 onCreate 方法,執(zhí)行時(shí)機(jī)比 Application#onCreate 還靠前,可以做一些初始化的工作,get 到了嗎?

這里需要注意的是,如果你的項(xiàng)目擁有多進(jìn)程,系統(tǒng)只會(huì)在主進(jìn)程中實(shí)例化一個(gè)你聲明的 ContentProvider,并不會(huì)在其他非主進(jìn)程中實(shí)例化 ContentProvider,如果在當(dāng)前進(jìn)程中 ContentProvider 沒(méi)有被實(shí)例化,那 ContentProvider#onCreate 就不會(huì)被調(diào)用,你的初始化代碼在當(dāng)前進(jìn)程中也就不會(huì)執(zhí)行,這時(shí)就需要在 Application#onCreate 中調(diào)用下 ContentProvider#query 執(zhí)行一下查詢操作,這時(shí) ContentProvider 就會(huì)在當(dāng)前進(jìn)程中實(shí)例化 (每個(gè)進(jìn)程中只會(huì)保證有一個(gè)實(shí)例),所以應(yīng)用到框架中就是,如果你需要在多個(gè)進(jìn)程中都進(jìn)行屏幕適配,那就需要在 Application#onCreate 中調(diào)用 AutoSize#initCompatMultiProcess 方法

進(jìn)階使用

雖然 AndroidAutoSize 不需要其他過(guò)多的配置,只需要在 AndroidManifest.xml 中填寫(xiě)下設(shè)計(jì)圖尺寸就能正常運(yùn)行,但 AndroidAutoSize 還是為大家準(zhǔn)備了很多可配置選項(xiàng),盡最大可能滿足大家日常開(kāi)發(fā)中的所有擴(kuò)展需求

所有的全局配置選項(xiàng)在 Demo 中都有介紹,每個(gè) API 中也都有詳細(xì)的注釋,在這里就不過(guò)多介紹了

自定義 Activity

AndroidManifest.xml 中填寫(xiě)的設(shè)計(jì)圖尺寸,是整個(gè)項(xiàng)目的全局設(shè)計(jì)圖尺寸,但是如果某些 Activity 頁(yè)面由于某些原因,設(shè)計(jì)師單獨(dú)出圖,這個(gè)頁(yè)面的設(shè)計(jì)圖尺寸和在 AndroidManifest.xml 中填寫(xiě)的設(shè)計(jì)圖尺寸不一樣該怎么辦呢?不要急,AndroidAutoSize 已經(jīng)為你考慮好了,讓這個(gè)頁(yè)面的 Activity 實(shí)現(xiàn) CustomAdapt 接口即可實(shí)現(xiàn)你的需求,CustomAdapt 接口的第一個(gè)方法可以修改當(dāng)前頁(yè)面的設(shè)計(jì)圖尺寸,第二個(gè)方法可以切換當(dāng)前頁(yè)面的適配基準(zhǔn),下面的注釋都解釋的很清楚

public class CustomAdaptActivity extends AppCompatActivity implements CustomAdapt {

     /**
     * 是否按照寬度進(jìn)行等比例適配 (為了保證在高寬比不同的屏幕上也能正常適配, 所以只能在寬度和高度之中選擇一個(gè)作為基準(zhǔn)進(jìn)行適配)
     *
     * @return {@code true} 為按照寬度進(jìn)行適配, {@code false} 為按照高度進(jìn)行適配
     */
    @Override
    public boolean isBaseOnWidth() {
        return false;
    }

     /**
     * 這里使用 iPhone 的設(shè)計(jì)圖, iPhone 的設(shè)計(jì)圖尺寸為 750px * 1334px, 高換算成 dp 為 667 (1334px / 2 = 667dp)
     * <p>
     * 返回設(shè)計(jì)圖上的設(shè)計(jì)尺寸, 單位 dp
     * {@link #getSizeInDp} 須配合 {@link #isBaseOnWidth()} 使用, 規(guī)則如下:
     * 如果 {@link #isBaseOnWidth()} 返回 {@code true}, {@link #getSizeInDp} 則應(yīng)該返回設(shè)計(jì)圖的總寬度
     * 如果 {@link #isBaseOnWidth()} 返回 {@code false}, {@link #getSizeInDp} 則應(yīng)該返回設(shè)計(jì)圖的總高度
     * 如果您不需要自定義設(shè)計(jì)圖上的設(shè)計(jì)尺寸, 想繼續(xù)使用在 AndroidManifest 中填寫(xiě)的設(shè)計(jì)圖尺寸, {@link #getSizeInDp} 則返回 {@code 0}
     *
     * @return 設(shè)計(jì)圖上的設(shè)計(jì)尺寸, 單位 dp
     */
    @Override
    public float getSizeInDp() {
        return 667;
    }
}

如果某個(gè) Activity 想放棄適配,讓這個(gè) Activity 實(shí)現(xiàn) CancelAdapt 接口即可,比如修改 density 影響到了老項(xiàng)目中的某些 Activity 頁(yè)面的布局效果,這時(shí)就可以讓這個(gè) Activity 實(shí)現(xiàn) CancelAdapt 接口

public class CancelAdaptActivity extends AppCompatActivity implements CancelAdapt {

}

自定義 Fragment

Fragment 的自定義方式和 Activity 是一樣的,只不過(guò)在使用前需要先在 App 初始化時(shí)開(kāi)啟對(duì) Fragment 的支持

AutoSizeConfig.getInstance().setCustomFragment(true);

實(shí)現(xiàn) CustomAdapt

public class CustomAdaptFragment extends Fragment implements CustomAdapt {

    @Override
    public boolean isBaseOnWidth() {
        return false;
    }

    @Override
    public float getSizeInDp() {
        return 667;
    }
}

實(shí)現(xiàn) CancelAdapt

public class CancelAdaptFragment extends Fragment implements CancelAdapt {

}

適配三方庫(kù)頁(yè)面

在使用主單位時(shí)可以使用 ExternalAdaptManager 來(lái)實(shí)現(xiàn)在不修改三方庫(kù)源碼的情況下,適配三方庫(kù)的所有頁(yè)面 (Activity、Fragment)

由于 AndroidAutoSize 要求需要自定義適配參數(shù)或取消適配的頁(yè)面必須實(shí)現(xiàn) CustomAdaptCancelAdapt,這時(shí)問(wèn)題就來(lái)了,三方庫(kù)是通過(guò)遠(yuǎn)程依賴的,我們無(wú)法修改它的源碼,這時(shí)我們?cè)趺醋屓綆?kù)的頁(yè)面也能實(shí)現(xiàn)自定義適配參數(shù)或取消適配呢?別急,這個(gè)需求 AndroidAutoSize 也已經(jīng)為你考慮好了,當(dāng)然不會(huì)讓你將三方庫(kù)下載到本地然后改源碼!

  • 通過(guò) ExternalAdaptManager#addExternalAdaptInfoOfActivity(Class, ExternalAdaptInfo) 將需要自定義的類和自定義適配參數(shù)添加進(jìn)方法即可替代實(shí)現(xiàn) CustomAdapt 的方式,這里 展示了使用方式,以及詳細(xì)的注釋

  • 通過(guò) ExternalAdaptManager#addCancelAdaptOfActivity(Class) 將需要取消適配的類添加進(jìn)方法即可替代實(shí)現(xiàn) CancelAdapt 的方式,這里 也展示了使用方式,以及詳細(xì)的注釋

需要注意的是 ExternalAdaptManager 的方法雖然可以添加任何類,但是只能支持 Activity、Fragment,并且 ExternalAdaptManager 是支持鏈?zhǔn)秸{(diào)用的,以便于持續(xù)添加多個(gè)頁(yè)面

當(dāng)然 ExternalAdaptManager 不僅可以對(duì)三方庫(kù)的頁(yè)面使用,也可以讓自己項(xiàng)目中的 Activity、Fragment 不用實(shí)現(xiàn) CustomAdapt、CancelAdapt 即可達(dá)到自定義適配參數(shù)和取消適配的功能

副單位

前面已經(jīng)介紹了 副單位 的應(yīng)用場(chǎng)景,這里就直接介紹 副單位 如何使用,副單位Demodemo-subunits

基本使用

首先和 主單位 一樣也需要先在 appAndroidManifest.xml 中填寫(xiě)上設(shè)計(jì)圖尺寸,但和 主單位 不一樣的是,當(dāng)在使用 副單位 時(shí) design_width_in_dpdesign_height_in_dp 的單位不需要一定是 dp,可以直接填寫(xiě)設(shè)計(jì)圖的 px 尺寸,在布局文件中每個(gè)控件的大小也可以直接填寫(xiě)設(shè)計(jì)圖上標(biāo)注的 px 尺寸,無(wú)需再將 px 轉(zhuǎn)換為 dp,這是 副單位的 特性之一,可以幫助大家提高開(kāi)發(fā)效率

<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>

由于 AndroidAutoSize 提供了 pt、in、mm 三種類型的 副單位 供使用者選擇,所以在使用 副單位 時(shí),還需要在 APP 初始化時(shí),通過(guò) UnitsManager#setSupportSubunits(Subunits) 方法選擇一個(gè)你喜歡的副單位,然后在布局文件中使用這個(gè)副單位進(jìn)行布局,三種類型的副單位,其實(shí)效果都是一樣,大家按喜歡的名字選擇即可

由于使用副單位是為了徹底屏蔽修改 density 所造成的對(duì)三方庫(kù)頁(yè)面、三方庫(kù)控件以及系統(tǒng)控件的布局效果的影響,所以在使用副單位時(shí)建議調(diào)用 UnitsManager#setSupportDP(false)UnitsManager#setSupportSP(false),關(guān)閉 AndroidAutoSize 對(duì) dpsp 的支持,AndroidAutoSize 為什么不在使用 副單位 時(shí)默認(rèn)關(guān)閉對(duì) dp、sp 的支持?因?yàn)樵试S同時(shí)支持 主單位副單位 可以幫助使用者在 主單位副單位 之間切換時(shí)更好的過(guò)渡,這點(diǎn)在前面就已經(jīng)提到過(guò)

UnitsManager 的詳細(xì)使用方法,在 demo-subunits 中都有展示,注釋也十分詳細(xì)

自定義 ActivityFragment

在使用 副單位 時(shí)自定義 ActivityFragment 的方式是和 主單位 是一樣的,這里就不再過(guò)多介紹了

適配三方庫(kù)頁(yè)面

如果你的項(xiàng)目在使用 副單位 并且關(guān)閉了對(duì) 主單位 (dp、sp) 的支持,這時(shí) ExternalAdaptManager 對(duì)三方庫(kù)的頁(yè)面是不起作用的,只對(duì)自己項(xiàng)目中的頁(yè)面起作用,除非三方庫(kù)的頁(yè)面也使用了副單位 (pt、in、mm) 進(jìn)行布局

其實(shí) 副單位 之所以能徹底屏蔽修改 density 所造成的對(duì)三方庫(kù)頁(yè)面、三方庫(kù)控件以及系統(tǒng)控件的布局效果的影響,就是因?yàn)槿綆?kù)頁(yè)面、三方庫(kù)控件以及系統(tǒng)控件基本上使用的都是 dp、sp 進(jìn)行布局,所以只要 AndroidAutoSize 關(guān)閉了對(duì) dp、sp 的支持,轉(zhuǎn)而使用 副單位 進(jìn)行布局,就能徹底屏蔽修改 density 所造成的對(duì)三方庫(kù)頁(yè)面、三方庫(kù)控件以及系統(tǒng)控件的布局效果的影響

但這也同樣意味著使用 副單位 就不能適配三方庫(kù)的頁(yè)面了,ExternalAdaptManager 也就對(duì)三方庫(kù)的頁(yè)面不起作用了

布局實(shí)時(shí)預(yù)覽

在開(kāi)發(fā)階段布局時(shí)的實(shí)時(shí)預(yù)覽是一個(gè)很重要的環(huán)節(jié),很多情況下 Android Studio 提供的默認(rèn)預(yù)覽設(shè)備并不能完全展示我們的設(shè)計(jì)圖,所以我們就需要自己創(chuàng)建模擬設(shè)備,dp、pt、in、mm 這四種單位的模擬設(shè)備創(chuàng)建方法請(qǐng)看 這里

總結(jié)

AndroidAutoSize 在經(jīng)歷了 240+ commit、60+ issues、6 個(gè)版本 的洗禮后,逐漸的穩(wěn)定了下來(lái),已經(jīng)在上個(gè)星期發(fā)布了首個(gè)正式版,在這里要感謝將 AndroidAutoSize 接入到自己項(xiàng)目中的上千個(gè)使用者,感謝他們的信賴,AndroidAutoSize 創(chuàng)建的初衷就是為了讓所有使用 今日頭條屏幕適配方案 的使用者能有一個(gè)可以一起交流、溝通的聚集地,所以后面也會(huì)持續(xù)的收集并解決 今日頭條屏幕適配方案的常見(jiàn)問(wèn)題,讓 今日頭條屏幕適配方案 變得更加成熟、穩(wěn)定

至此本系列的第三篇文章也就完結(jié)了,這也預(yù)示著這個(gè)系列連載的終結(jié),這篇文章建議結(jié)合系列的第一篇文章 騷年你的屏幕適配方式該升級(jí)了!(一)-今日頭條適配方案 一起看,這樣可以對(duì) 今日頭條屏幕適配方案 有一個(gè)更深入的理解,如果你能將整個(gè)系列的文章都全部認(rèn)真看完,那你對(duì) Android 屏幕適配領(lǐng)域的相關(guān)知識(shí)絕對(duì)會(huì)有一個(gè)飛速的提升!

當(dāng)你的項(xiàng)目需要切換某個(gè)框架時(shí),你會(huì)怎么去考察、分析、對(duì)比現(xiàn)有的開(kāi)源方案,并有足夠的理由去選擇或優(yōu)化一個(gè)最適合自己項(xiàng)目的方案呢?其實(shí)整個(gè)系列文章可以看作是我怎么去選擇同類型開(kāi)源方案的過(guò)程,你以后當(dāng)遇到同樣的選擇也可以參照我的思維方式去處理,當(dāng)然如果以后面試官問(wèn)到你屏幕適配相關(guān)的問(wèn)題,你能將我如何選擇、分析、對(duì)比已有方案的過(guò)程以及文章中的核心知識(shí)點(diǎn)告訴給面試官,那肯定比你直接說(shuō)一句我使用的是某某開(kāi)源庫(kù)有價(jià)值得多


以下是 騷年你的屏幕適配方式該升級(jí)了! 系列文章,歡迎轉(zhuǎn)發(fā)以及分享:

最后編輯于
?著作權(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)容