騷年你的螢幕適配方式該升級了!-SmallestWidth 限定符適配方案

JessYan發表於2018-09-19

原文地址: www.jianshu.com/p/2aded8bb6…

以下是 騷年你的螢幕適配方式該升級了! 系列文章,歡迎轉發以及分享:

加入技術交流 QQ 群 455850365

前言

ok,根據上一篇文章 騷年你的螢幕適配方式該升級了!-今日頭條適配方案 的承諾,本文是這個系列的第二篇文章,這篇文章會詳細講解 smallestWidth 限定符螢幕適配方案

瞭解我的朋友一定知道,MVPArms 一直使用的是 鴻神AndroidAutoLayout 螢幕適配方案,得益於 AndroidAutoLayout 的便捷,所以我對螢幕適配領域研究的不是很多,AndroidAutoLayout 停止維護後,我也一直在找尋著替代方案,直到 今日頭條螢幕適配方案 刷屏,後來又無意間看到了 smallestWidth 限定符螢幕適配方案,這才慢慢的將研究方向轉向了螢幕適配領域

最近一個月才開始慢慢惡補 Android 螢幕適配的相關知識,對這兩個方案也進行了更深入的研究,可以說從一個小白慢慢成長而來,所以我明白小白的痛,因此在上一篇文章 騷年你的螢幕適配方式該升級了!-今日頭條適配方案 中,把 今日頭條螢幕適配方案 講得非常的細,儘量把每一個知識點都描述清晰,深怕小白漏掉每一個細節,這篇文章我也會延續上一篇文章的優良傳統,將 smallestWidth 限定符螢幕適配方案 的每一個知識點都描述清晰

順便說一句,感謝大家對 AndroidAutoSize 的支援,我只是在上一篇文章中提了一嘴我剛釋出的螢幕適配框架 AndroidAutoSize,還沒給出詳細的介紹和原理剖析 (原計劃在本系列的第三篇文章中釋出),AndroidAutoSize 就被大家推上了 Github Trending,一個多星期就拿了 2k+ stars,隨著關注度的增加,我在這段時間裡也累壞了,issues 就沒斷過,不到半個月就提交了 200 多次 commit,但累並快樂著,在這裡要再次感謝大家對 AndroidAutoSize 的認可

談談對百分比庫的看法

是這樣的,在上篇文章中有一些兄弟提了一些觀點,我很是認同,但是我站在執行者的角度來看待這個問題,也有一些不同的觀點,以下是我在上篇文章中的回覆

大家要注意了!這些觀點其實針對的是所有以百分比縮放佈局的庫,而不只是今日頭條螢幕適配方案,所以這些觀點也同樣適用於 smallestWidth 限定符螢幕適配方案,這點有很多人存在誤解,所以一定要注意!

上圖的每一個方框都代表一種 Android 裝置的螢幕,Android系統碎片化機型以及螢幕尺寸碎片化螢幕解析度碎片化 有多嚴重大家可以通過 友盟指數 瞭解一下,有些時候在某些事情的決斷標準上,並不能按照事情的對錯來決斷,大多數情況還是要分析成本,收益等多種因素,通過利弊來決斷,每個人的利弊標準又都不一樣,所以每個人的觀點也都會有差別,但也都應該得到尊重,所以我只是說說自己的觀點,也不否認任何人的觀點

方案是死的人是活的,在某些大屏手機或平板電腦上,您也可以採用其他適配方案和百分比庫結合使用,比如針對某個螢幕區間的裝置單獨出一套設計圖以顯示比小螢幕手機更多更精細的內容,來達到與百分比庫互補的效果,沒有一個方案可以說自己是完美的,但我們能清晰的認識到不同方案的優缺點,將它們的優點相結合,才能應付更復雜的開發需求,產出最好的產品

友情提示: 下面要介紹的 smallestWidth 限定符螢幕適配方案,原理也同樣是按照百分比縮放佈局,理論上也會存在上面所說的 大屏手機和小屏手機顯示的內容相同 的問題,選擇與否請仔細斟酌

簡介 smallestWidth 限定符適配方案

這個方案的的使用方式和我們平時在佈局中引用 dimens 無異,核心點在於生成 dimens.xml 檔案,但是已經有大神幫我們做了這 一步

├── src/main
│   ├── res
│   ├── ├──values
│   ├── ├──values-800x480
│   ├── ├──values-860x540
│   ├── ├──values-1024x600
│   ├── ├──values-1024x768
│   ├── ├──...
│   ├── ├──values-2560x1440
複製程式碼

如果有人還記得上面這種 寬高限定符螢幕適配方案 的話,就可以把 smallestWidth 限定符螢幕適配方案 當成這種方案的升級版,smallestWidth 限定符螢幕適配方案 只是把 dimens.xml 檔案中的值從 px 換成了 dp,原理和使用方式都是沒變的,這些在上面的文章中都有介紹,下面就直接開始剖析原理,smallestWidth 限定符螢幕適配方案 長這樣?

├── src/main
│   ├── res
│   ├── ├──values
│   ├── ├──values-sw320dp
│   ├── ├──values-sw360dp
│   ├── ├──values-sw400dp
│   ├── ├──values-sw411dp
│   ├── ├──values-sw480dp
│   ├── ├──...
│   ├── ├──values-sw600dp
│   ├── ├──values-sw640dp
複製程式碼

原理

其實 smallestWidth 限定符螢幕適配方案 的原理也很簡單,開發者先在專案中根據主流螢幕的 最小寬度 (smallestWidth) 生成一系列 values-sw<N>dp 資料夾 (含有 dimens.xml 檔案),當把專案執行到裝置上時,系統會根據當前裝置螢幕的 最小寬度 (smallestWidth) 去匹配對應的 values-sw<N>dp 資料夾,而對應的 values-sw<N>dp 資料夾中的 dimens.xml 文字中的值,又是根據當前裝置螢幕的 最小寬度 (smallestWidth) 而定製的,所以一定能適配當前裝置

如果系統根據當前裝置螢幕的 最小寬度 (smallestWidth) 沒找到對應的 values-sw<N>dp 資料夾,則會去尋找與之 最小寬度 (smallestWidth) 相近的 values-sw<N>dp 資料夾,系統只會尋找小於或等於當前裝置 最小寬度 (smallestWidth)values-sw<N>dp,這就是優於 寬高限定符螢幕適配方案 的容錯率,並且也可以少生成很多 values-sw<N>dp 資料夾,減輕 App 的體積

什麼是 smallestWidth

smallestWidth 翻譯為中文的意思就是 最小寬度,那這個 最小寬度 是什麼意思呢?

系統會根據當前裝置螢幕的 最小寬度 來匹配 values-sw<N>dp,為什麼不是根據 寬度 來匹配,而要加上 最小 這兩個字呢?

這就要說到,移動裝置都是允許螢幕可以旋轉的,當螢幕旋轉時,螢幕的高寬就會互換,加上 最小 這兩個字,是因為這個方案是不區分螢幕方向的,它只會把螢幕的高度和寬度中值最小的一方認為是 最小寬度,這個 最小寬度 是根據螢幕來定的,是固定不變的,意思是不管您怎麼旋轉螢幕,只要這個螢幕的高度大於寬度,那系統就只會認定寬度的值為 最小寬度,反之如果螢幕的寬度大於高度,那系統就會認定螢幕的高度的值為 最小寬度

如果想讓螢幕寬度隨著螢幕的旋轉而做出改變該怎麼辦呢?可以再根據 values-w<N>dp (去掉 sw 中的 s) 生成一套資原始檔

如果想區分螢幕的方向來做適配該怎麼辦呢?那就只有再根據 螢幕方向限定符 生成一套資原始檔咯,字尾加上 -land-port 即可,像這樣,values-sw400dp-land (最小寬度 400 dp 橫向)values-sw400dp-port (最小寬度 400 dp 縱向)

smallestWidth 的值是怎麼算的

要先算出當前裝置的 smallestWidth 值我們才能知道當前裝置該匹配哪個 values-sw<N>dp 資料夾

ok,還是按照上一篇文章的敘述方式,現在來舉慄說明,幫助大家更好理解

我們假設裝置的螢幕資訊是 1920 * 1080480 dpi

根據上面的規則我們要在螢幕的高度和寬度中選擇值最小的一方作為最小寬度,1080 < 1920,明顯 1080 px 就是我們要找的 最小寬度 的值,但 最小寬度 的單位是 dp,所以我們要把 px 轉換為 dp

幫助大家再鞏固下基礎,下面的公式一定不能再忘了!

px / density = dpDPI / 160 = density,所以最終的公式是 px / (DPI / 160) = dp

所以我們得到的 最小寬度 的值是 360 dp (1080 / (480 / 160) = 360)

現在我們已經算出了當前裝置的最小寬度是 360 dp,我們曉得系統會根據這個 最小寬度 幫助我們匹配到 values-sw360dp 資料夾下的 dimens.xml 檔案,如果專案中沒有 values-sw360dp 這個資料夾,系統才會去匹配相近的 values-sw<N>dp 資料夾

dimens.xml 檔案是整個方案的核心所在,所以接下來我們再來看看 values-sw360dp 資料夾中的這個 dimens.xml 是根據什麼原理生成的

dimens.xml 生成原理

因為我們在專案佈局中引用的 dimens 的實際值,來源於根據當前裝置螢幕的 最小寬度 所匹配的 values-sw<N>dp 資料夾中的 dimens.xml,所以搞清楚 dimens.xml 的生成原理,有助於我們理解 smallestWidth 限定符螢幕適配方案

說到 dimens.xml 的生成,就要涉及到兩個因數,第一個因素是 最小寬度基準值,第二個因素就是您的專案需要適配哪些 最小寬度,通俗理解就是需要生成多少個 values-sw<N>dp 資料夾

第一個因素

最小寬度基準值 是什麼意思呢?簡單理解就是您需要把裝置的螢幕寬度分為多少份,假設我們現在把專案的 最小寬度基準值 定為 360,那這個方案就會理解為您想把所有裝置的螢幕寬度都分為 360 份,方案會幫您在 dimens.xml 檔案中生成 1360dimens 引用,比如 values-sw360dp 中的 dimens.xml 是長這樣的

<?xml version="1.0" encoding="UTF-8"?>
<resources>
	<dimen name="dp_1">1dp</dimen>
	<dimen name="dp_2">2dp</dimen>
	<dimen name="dp_3">3dp</dimen>
	<dimen name="dp_4">4dp</dimen>
	<dimen name="dp_5">5dp</dimen>
	<dimen name="dp_6">6dp</dimen>
	<dimen name="dp_7">7dp</dimen>
	<dimen name="dp_8">8dp</dimen>
	<dimen name="dp_9">9dp</dimen>
	<dimen name="dp_10">10dp</dimen>
	...
	<dimen name="dp_356">356dp</dimen>
	<dimen name="dp_357">357dp</dimen>
	<dimen name="dp_358">358dp</dimen>
	<dimen name="dp_359">359dp</dimen>
	<dimen name="dp_360">360dp</dimen>
</resources>
複製程式碼

values-sw360dp 指的是當前裝置螢幕的 最小寬度360dp (該裝置高度大於寬度,則最小寬度就是寬度,所以該裝置寬度為 360dp),把螢幕寬度分為 360 份,剛好每份等於 1dp,所以每個引用都遞增 1dp,值最大的 dimens 引用 dp_360 值也是 360dp,剛好覆蓋螢幕寬度

下面再來看看將 最小寬度基準值 定為 360 時,values-sw400dp 中的 dimens.xml 長什麼樣

<?xml version="1.0" encoding="UTF-8"?>
<resources>
	<dimen name="dp_1">1.1111dp</dimen>
	<dimen name="dp_2">2.2222dp</dimen>
	<dimen name="dp_3">3.3333dp</dimen>
	<dimen name="dp_4">4.4444dp</dimen>
	<dimen name="dp_5">5.5556dp</dimen>
	<dimen name="dp_6">6.6667dp</dimen>
	<dimen name="dp_7">7.7778dp</dimen>
	<dimen name="dp_8">8.8889dp</dimen>
	<dimen name="dp_9">10.0000dp</dimen>
	<dimen name="dp_10">11.1111dp</dimen>
	...
	<dimen name="dp_355">394.4444dp</dimen>
	<dimen name="dp_356">395.5556dp</dimen>
	<dimen name="dp_357">396.6667dp</dimen>
	<dimen name="dp_358">397.7778dp</dimen>
	<dimen name="dp_359">398.8889dp</dimen>
	<dimen name="dp_360">400.0000dp</dimen>
</resources>
複製程式碼

values-sw400dp 指的是當前裝置螢幕的 最小寬度400dp (該裝置高度大於寬度,則最小寬度就是寬度,所以該裝置寬度為 400dp),把螢幕寬度同樣分為 360份,這時每份就等於 1.1111dp 了,每個引用都遞增 1.1111dp,值最大的 dimens 引用 dp_360 同樣剛好覆蓋螢幕寬度,為 400dp

通過兩個 dimens.xml 檔案的比較,dimens.xml 的生成原理一目瞭然,方案會先確定 最小寬度基準值,然後將每個 values-sw<N>dp 中的 dimens.xml 檔案都分配與 最小寬度基準值 相同的份數,再根據公式 螢幕最小寬度 / 份數 (最小寬度基準值) 求出每份佔多少 dp,保證不管在哪個 values-sw<N>dp 中,份數 (最小寬度基準值) * 每份佔的 dp 值 的結果都是剛好覆蓋螢幕寬度,所以在 份數 不變的情況下,只需要根據螢幕的寬度在不同的裝置上動態調整 每份佔的 dp 值,就能完成適配

這樣就能保證不管將專案執行到哪個裝置上,只要當前裝置能匹配到對應的 values-sw<N>dp 資料夾,那佈局中的 dimens 引用就能根據當前螢幕的情況進行縮放,保證能完美適配,如果沒有匹配到對應的 values-sw<N>dp 資料夾,也沒關係,它會去尋找與之相近的 values-sw<N>dp 資料夾,雖然在這種情況下,佈局中的 dimens 引用的值可能有些許誤差,但是也能保證最大程度的完成適配

說到這裡,那大家就應該就會明白我為什麼會說 smallestWidth 限定符螢幕適配方案 的原理也同樣是按百分比進行佈局,如果在佈局中,一個 View 的寬度引用 dp_100,那不管執行到哪個裝置上,這個 View 的寬度都是當前裝置螢幕總寬度的 360分之100,前提是專案提供有當前裝置螢幕對應的 values-sw<N>dp,如果沒有對應的 values-sw<N>dp,就會去尋找相近的 values-sw<N>dp,這時就會存在誤差了,至於誤差是大是小,這就要看您的第二個因數怎麼分配了

其實 smallestWidth 限定符螢幕適配方案 的原理和 今日頭條螢幕適配方案 挺像的,今日頭條螢幕適配方案 是根據螢幕的寬度或高度動態調整每個裝置的 density (每 dp 佔當前裝置螢幕多少畫素),而 smallestWidth 限定符螢幕適配方案 同樣是根據螢幕的寬度動態調整每個裝置 每份佔的 dp 值

第二個因素

第二個因數是需要適配哪些 最小寬度?比如您想適配的 最小寬度320dp360dp400dp411dp480dp,那方案就會為您的專案生成 values-sw320dpvalues-sw360dpvalues-sw400dpvalues-sw411dpvalues-sw480dp 這幾個資原始檔夾,像這樣?

├── src/main
│   ├── res
│   ├── ├──values
│   ├── ├──values-sw320dp
│   ├── ├──values-sw360dp
│   ├── ├──values-sw400dp
│   ├── ├──values-sw411dp
│   ├── ├──values-sw480dp
複製程式碼

方案會為您需要適配的 最小寬度,在專案中生成一系列對應的 values-sw<N>dp,在前面也說了,如果某個裝置沒有為它提供對應的 values-sw<N>dp,那它就會去尋找相近的 values-sw<N>dp,但如果這個相近的 values-sw<N>dp 與期望的 values-sw<N>dp 差距太大,那適配效果也就會大打折扣

那是不是 values-sw<N>dp 資料夾生成的越多,覆蓋越多市面上的裝置,就越好呢?

也不是,因為每個 values-sw<N>dp 資料夾其實都會佔用一定的 App 體積,values-sw<N>dp 資料夾越多,App 的體積也就會越大

所以一定要合理分配 values-sw<N>dp,以越少的 values-sw<N>dp 資料夾,覆蓋越多的機型

驗證方案可行性

原理講完了,我們還是按照老規矩,來驗證一下這個方案是否可行?

假設設計圖總寬度為 375 dp,一個 View 在這個設計圖上的尺寸是 50dp * 50dp,這個 View 的寬度佔整個設計圖寬度的 13.3% (50 / 375 = 0.133)

在使用 smallestWidth 限定符螢幕適配方案 時,需要提供 最小寬度基準值 和需要適配哪些 最小寬度,我們就把 最小寬度基準值 設定為 375 (和 設計圖 一致),這時方案就會為我們需要適配的 最小寬度 生成對應的 values-sw<N>dp 資料夾,資料夾中的 dimens.xml 檔案是由從 1375 組成的 dimens 引用,把所有裝置的螢幕寬度都分為 375 份,所以在佈局檔案中我們應該把這個 View 的高寬都引用 dp_50

下面就來驗證下在使用 smallestWidth 限定符螢幕適配方案 的情況下,這個 View 與螢幕寬度的比例在解析度不同的裝置上是否還能保持和設計圖中的比例一致

驗證裝置 1

裝置 1 的螢幕總寬度為 1080 px,螢幕總高度為 1920 pxDPI480

裝置 1 的螢幕高度大於螢幕寬度,所以 裝置 1最小寬度 為螢幕寬度,再根據公式 px / (DPI / 160) = dp,求出 裝置 1最小寬度 的值為 360 dp (1080 / (480 / 160) = 360)

根據 裝置 1最小寬度 應該匹配的是 values-sw360dp 這個資料夾,假設 values-sw360dp 資料夾及裡面的 dimens.xml 已經生成,且是按 最小寬度基準值375 生成的,360 / 375 = 0.96,所以每份佔的 dp 值為 0.96dimens.xml 裡面的內容是長下面這樣的?

<?xml version="1.0" encoding="UTF-8"?>
<resources>
	<dimen name="dp_1">0.96dp</dimen>
	<dimen name="dp_2">1.92dp</dimen>
	<dimen name="dp_3">2.88dp</dimen>
	<dimen name="dp_4">3.84dp</dimen>
	<dimen name="dp_5">4.8dp</dimen>
	...
	<dimen name="dp_50">48dp</dimen>
	...
	<dimen name="dp_371">356.16dp</dimen>
	<dimen name="dp_372">357.12dp</dimen>
	<dimen name="dp_373">358.08dp</dimen>
	<dimen name="dp_374">359.04dp</dimen>
	<dimen name="dp_375">360dp</dimen>
</resources>
複製程式碼

可以看到這個 View 在佈局中引用的 dp_50,最終在 values-sw360dp 中定格在了 48 dp,所以這個 View裝置 1 上的高寬都為 48 dp,系統最後會將高寬都換算成 px,根據公式 dp * (DPI / 160) = px,所以這個 View 的高寬換算為 px 後等於 144 px (48 * (480 / 160) = 144)

144 / 1080 = 0.133View 的實際寬度與 螢幕總寬度 的比例和 View 在設計圖中的比例一致 (50 / 375 = 0.133),所以完成了等比例縮放

某些裝置的高寬是和 裝置 1 相同的,但是 DPI 可能不同,而由於 smallestWidth 限定符螢幕適配方案 並沒有像 今日頭條螢幕適配方案 一樣去自行修改 density,所以系統就會使用預設的公式 DPI / 160 求出 densitydensity 又會影響到 dppx 的換算,因此 DPI 的變化,是有可能會影響到 smallestWidth 限定符螢幕適配方案

所以我們再來試試在這種特殊情況下 smallestWidth 限定符螢幕適配方案 是否也能完成適配

驗證裝置 2

裝置 2 的螢幕總寬度為 1080 px,螢幕總高度為 1920 pxDPI420

裝置 2 的螢幕高度大於螢幕寬度,所以 裝置 2最小寬度 為螢幕寬度,再根據公式 px / (DPI / 160) = dp,求出 裝置 2最小寬度 的值為 411.429 dp (1080 / (420 / 160) = 411.429)

根據 裝置 2最小寬度 應該匹配的是 values-sw411dp 這個資料夾,假設 values-sw411dp 資料夾及裡面的 dimens.xml 已經生成,且是按 最小寬度基準值375 生成的,411 / 375 = 1.096,所以每份佔的 dp 值為 1.096dimens.xml 裡面的內容是長下面這樣的?

<?xml version="1.0" encoding="UTF-8"?>
<resources>
	<dimen name="dp_1">1.096dp</dimen>
	<dimen name="dp_2">2.192dp</dimen>
	<dimen name="dp_3">3.288dp</dimen>
	<dimen name="dp_4">4.384dp</dimen>
	<dimen name="dp_5">5.48dp</dimen>
	...
	<dimen name="dp_50">54.8dp</dimen>
	...
	<dimen name="dp_371">406.616dp</dimen>
	<dimen name="dp_372">407.712dp</dimen>
	<dimen name="dp_373">408.808dp</dimen>
	<dimen name="dp_374">409.904dp</dimen>
	<dimen name="dp_375">411dp</dimen>
</resources>
複製程式碼

可以看到這個 View 在佈局中引用的 dp_50,最終在 values-sw411dp 中定格在了 54.8dp,所以這個 View裝置 2 上的高寬都為 54.8 dp,系統最後會將高寬都換算成 px,根據公式 dp * (DPI / 160) = px,所以這個 View 的高寬換算為 px 後等於 143.85 px (54.8 * (420 / 160) = 143.85)

143.85 / 1080 = 0.133View 的實際寬度與 螢幕總寬度 的比例和 View 在設計圖中的比例一致 (50 / 375 = 0.133),所以完成了等比例縮放

雖然 View裝置 2 上的高寬是 143.85 px,比 裝置 1144 px 少了 0.15 px,但是誤差非常小,整體的比例並沒有發生太大的變化,是完全可以接受的

這個誤差是怎麼引起的呢,因為 裝置 2最小寬度 的實際值是 411.429 dp,但是匹配的 values-sw411dp 捨去了小數點後面的位數 (切記!系統會去尋找小於或等於 411.429 dp 的 values-sw<N>dp,所以 values-sw412dp 這個資料夾,裝置 2 是匹配不了的),所以才存在了一定的誤差,因此上面介紹的第二個因數是非常重要的,這直接決定誤差是大還是小

可以看到即使在高寬一樣但 DPI 不一樣的裝置上,smallestWidth 限定符螢幕適配方案 也能完成等比例適配,證明這個方案是可行的,如果大家還心存疑慮,也可以再試試其他解析度的裝置,其實到最後得出的比例都是在 0.133 左右,唯一的變數就是第二個因數,如果您生成的 values-sw<N>dp 與裝置實際的 最小寬度 差別不大,那誤差也就在能接受的範圍內,如果差別很大,那就直接 GG

優點

  1. 非常穩定,極低概率出現意外

  2. 不會有任何效能的損耗

  3. 適配範圍可自由控制,不會影響其他三方庫

  4. 在外掛的配合下,學習成本低

缺點

  1. 在佈局中引用 dimens 的方式,雖然學習成本低,但是在日常維護修改時較麻煩

  2. 侵入性高,如果專案想切換為其他螢幕適配方案,因為每個 Layout 檔案中都存在有大量 dimens 的引用,這時修改起來工作量非常巨大,切換成本非常高昂

  3. 無法覆蓋全部機型,想覆蓋更多機型的做法就是生成更多的資原始檔,但這樣會增加 App 體積,在沒有覆蓋的機型上還會出現一定的誤差,所以有時需要在適配效果和佔用空間上做一些抉擇

  4. 如果想使用 sp,也需要生成一系列的 dimens,導致再次增加 App 的體積

  5. 不能自動支援橫豎屏切換時的適配,如上文所說,如果想自動支援橫豎屏切換時的適配,需要使用 values-w<N>dp螢幕方向限定符 再生成一套資原始檔,這樣又會再次增加 App 的體積

  6. 不能以高度為基準進行適配,考慮到這個方案的名字本身就叫 最小寬度限定符適配方案,所以在使用這個方案之前就應該要知道這個方案只能以寬度為基準進行適配,為什麼現在的螢幕適配方案只能以高度或寬度其中的一個作為基準進行適配,請看 這裡

使用中的問題

這時有人就會問了,設計師給的設計圖只標註了 px,使用這個方案時,那不是還要先將 px 換算成 dp

其實也可以不用換算的,那這是什麼騷操作呢?

很簡單,你把設計圖的 px 總寬度設定成 最小寬度基準值 就可以了,還是以前面驗證可行性的例子

我們在前面驗證可行性時把 最小寬度基準值 設定成了 375,為什麼是 375 呢?因為設計圖的總寬度為 375 dp,如果換算成 px,總寬度就是 750 px,我們這時把 最小寬度基準值 設定成 750,然後看看 values-sw360dp 中的 dimens.xml 長什麼樣?

<?xml version="1.0" encoding="UTF-8"?>
<resources>
	<dimen name="px_1">0.48dp</dimen>
	<dimen name="px_2">0.96dp</dimen>
	<dimen name="px_3">1.44dp</dimen>
	<dimen name="px_4">1.92dp</dimen>
	<dimen name="px_5">2.4dp</dimen>
	...
	<dimen name="px_50">24dp</dimen>
	...
	<dimen name="px_100">48dp</dimen>
	...
	<dimen name="px_746">358.08dp</dimen>
	<dimen name="px_747">358.56dp</dimen>
	<dimen name="px_748">359.04dp</dimen>
	<dimen name="px_749">359.52dp</dimen>
	<dimen name="px_750">360dp</dimen>
</resources>
複製程式碼

360 dp 被分成了 750 份,相比之前的 375 份,現在 每份佔的 dp 值 正好減少了一半,還記得在驗證可行性的例子中那個 View 的尺寸是多少嗎?50dp * 50dp,如果設計圖只標註 px,那這個 View 在設計圖上的的尺寸應該是 100px * 100px,那我們直接根據設計圖上標註的 px,想都不用想直接在佈局中引用 px_100 就可以了,因為在 375 份時的 dp_50 剛好等於 750 份時的 px_100 (值都是 48 dp),所以這時的適配效果和之前驗證可行性時的適配效果沒有任何區別

看懂了嗎?直接將 最小寬度基準值 和佈局中的引用都以 px 作為單位就可以直接填寫設計圖上標註的 px

總結

關於文中所列出的優缺點,列出的缺點數量確實比列出的優點數量多,但 缺點 3缺點 4缺點 5 其實都可以歸納於 佔用 App 體積 這一個缺點,因為他們都可以通過增加資原始檔來解決問題,而 缺點 6 則是這個方案的特色,只能以寬度為基準進行適配,這個從這個方案的名字就能看出

請大家千萬不要曲解文章的意思,不要只是單純的對比優缺點的數量,缺點的數量大於優點的數量就一定是這個方案不行?沒有一個方案是完美的,每個人的需求也都不一樣,作為一篇科普類文章我只可能把這個方案描述得儘可能的全面

這個方案能給你帶來什麼,不能給你帶來什麼,我必須客觀的描述清楚,這樣才有助你做出決定,你應該注重的是在這些優缺點裡什麼是我能接受的,什麼是我不能接受的,是否能為了某些優點做出某些妥協,而不只是單純的去看數量,這樣毫無意義,有些人就是覺得穩定性最重要,其他的都可以做出妥協,那其他缺點對於他來說都是無所謂的

好了,這個系列的第二篇文章講完了,這篇文章也是按照上篇文章的優良傳統,寫的非常詳細,哪怕是新手我相信也應該能看懂,為什麼這麼多人都不知道自己該選擇什麼樣的方案,就是因為自己都沒搞懂這些方案的原理,懂了原理過後才知道這些方案是否是自己想要的

接下來的第三篇文章會詳細講解兩個方案的深入對比以及該如何選擇,並剖析我根據 今日頭條螢幕適配方案 優化的螢幕適配框架 AndroidAutoSize 的原理,敬請期待

如果大家想使用 smallestWidth 限定符螢幕適配方案,可以參考 這篇文章,裡面提供有自動生成資原始檔的外掛和 Demo,由於我並沒有在專案中使用 smallestWidth 限定符螢幕適配方案,所以如果在文章中有遺漏的知識點請諒解以及補充,感謝!

公眾號

搜尋關注我的公眾號 JessYan,一起學習進步,如果框架有更新,我也會在公眾號上第一時間通知大家


以下是 騷年你的螢幕適配方式該升級了! 系列文章,歡迎轉發以及分享:


Hello 我叫 JessYan,如果您喜歡我的文章,可以在以下平臺關注我

-- The end

相關文章