Android屏幕適配方案分析

爲何要屏幕適配

Android開發過程當中咱們經常使用的尺寸單位有px、dp,還有一種sp通常是用於字體的大小。可是因爲px是像素單位,好比咱們一般說的手機分辨例如1920*1080都是px的單位。如今Android屏幕分辨率碎片化720x1280、1080x1920、2280x1080,這就形成例如187px會在各個分辨率的機型上都是顯示同樣大小的,那確定不是咱們想要的效果,因此用px單位咱們是難以達到適配效果的,那麼爲何用dp能夠呢?android

使用px單位從左到右依次爲 480 * 800、1080 * 1920、1440 * 2560api

使用dp單位從左到右依次爲 480 * 800、1080 * 1920、1440 * 2560bash

屏幕總寬度依次爲 320dp、415dp、411dppost

那麼什麼是dp?

dp指的是設備獨立像素,以dp爲尺寸單位的控件,在不一樣分辨率和尺寸的手機上表明瞭不一樣的真實像素,好比在分辨率較低的手機中,可能1dp=1px,而在分辨率較高的手機中,可能1dp=2px,這樣的話,一個187dp高度的控件,在不一樣的手機中就能表現出差很少的大小了。性能

dp如何計算成px

android中的dp在渲染前會將dp轉爲px,計算公式:學習

  • px = density * dp;字體

  • density = dpi / 160;spa

  • px = dp * (dpi / 160);插件

而dpi是根據屏幕真實的分辨率和尺寸來計算的,每一個設備均可能不同的。設計

因爲density不是固定不變的,因此每一個分辨率不一樣的設備他們的density都確定不相等,這樣就會形成每一個設備的寬/高對應的總dp都是不一樣的,假設480 * 800分辨率的density是1.51080 * 1920分辨率的density是2.61440 * 2560分辨率的density是3.5。那麼它們對應的寬度總dp = (寬度px) / density,分別爲320dp、415dp、411dp。能夠看出單位爲dp的時候三個設備之間的差距就不是很大了,可是這樣確定仍是不能知足咱們對屏幕適配的要求的。下面來看看Android常見的三種比較成熟的屏幕適配方案,並分析這幾種方案的優劣。

屏幕適配方案

1.1 寬高限定符適配

設定一個基準的分辨率,也就是設計圖對應的分辨率,其餘分辨率都根據這個基準分辨率來計算,在不一樣的尺寸文件夾內部,根據該尺寸編寫對應的dimens文件。

好比咱們的設計圖 375 * 667爲基準分辨率

  • 寬度爲375,將任何分辨率的寬度整分爲375份,取值爲x1-x375

  • 高度爲667,將任何分辨率的高度整分爲667份,取值爲y1-y667

那麼對於1080*1920的分辨率的dimens文件來講,

  • x1=(1080/375)*1=2.88px

  • x2=(1080/375)*2=5.76px

  • y1=(1920/667)*1=2.87px

  • y2=(1920/667)*2=5.75px

當代碼裏面引用高度爲y_187,在APP運行時會根據當前設備分辨率去找對應xml文件中對應的高度,咱們就能夠按照設計稿上的尺寸填寫相對應的dimens引用了,這樣基本解決了咱們的適配問題,並且極大的提高了咱們UI開發的效率。

驗證方案

簡單經過計算驗證下這種方案是否能達到適配的效果,例如設計圖上有一個寬187dp的View。

480 * 800

  • 設計圖佔寬比: 187dp / 375dp = 0.498

  • 實際在480 * 800佔寬比 = 187 * 1.28px / 480 = 0.498

1080 * 1920

  • 設計圖佔寬比: 187dp / 375dp = 0.498

  • 實際在1080 * 1920佔寬比 = 187 * 2.88px / 1080 = 0.498

  • 計算高同理

可是這個方案有一個致命的缺陷,那就是須要精準命中才能適配,好比1920x1080的手機就必定要找到1920x1080的限定符,不然就只能用統一的默認的dimens文件了。而使用默認的尺寸的話,UI就極可能變形,簡單說,就是容錯機制不好。

1.2 smallestWidth適配

smallestWidth適配,或者叫sw限定符適配。指的是Android會識別屏幕可用高度和寬度的最小尺寸的dp值(其實就是手機的寬度值),而後根據識別到的結果去資源文件中尋找對應限定符的文件夾下的資源文件。

這種機制和上文提到的寬高限定符適配原理上是同樣的,都是系統經過特定的規則來選擇對應的文件。

能夠把 smallestWidth 限定符屏幕適配方案 當成這種方案的升級版,smallestWidth 限定符屏幕適配方案 只是把 dimens.xml 文件中的值從 px 換成了 dp,原理和使用方式都是沒變的

├── src/main
│   ├── res
│   ├── ├──values
│   ├── ├──values-sw320dp
│   ├── ├──values-sw360dp
│   ├── ├──values-sw400dp
│   ├── ├──values-sw411dp
│   ├── ├──values-sw480dp
│   ├── ├──...
│   ├── ├──values-sw600dp
│   ├── ├──values-sw640dp

複製代碼

驗證方案

1920 * 1080分辨率的手機,dpi爲420,咱們一樣設置一個View爲187dp寬

  • density = (dpi = 420) / 160 = 2.6
  • 屏幕總寬度dp = 1080 / density = 415
  • 找到文件夾values-sw410dp下的187dp = 204.45dp
  • 經過公式px = density * dp,計算出px = 531.57
  • 算出佔屏幕寬度的比例,56.86 / 1080 = 0.492

1440 * 2560分辨率的手機,dpi爲560,咱們一樣設置一個View爲187dp寬

  • density = (dpi = 420) / 160 = 3.5
  • 屏幕總寬度dp = 1440 / density = 411
  • 找到文件夾values-sw410dp下的187dp = 204.45dp
  • 經過公式px = density * dp,計算出px = 715.57
  • 算出佔屏幕寬度的比例,715.57 / 1440 = 0.496

由於識別的文件夾是values-sw410dp的文件夾,可是屏幕寬度爲415dp和411dp,因此最後計算出的佔比會有一點點偏差,基本能夠忽略不計,能夠達到相對比較準確的適配效果

優勢

  1. 很是穩定,極低機率出現意外
  2. 不會有任何性能的損耗
  3. 適配範圍可自由控制,不會影響其餘三方庫
  4. 在插件的配合下,學習成本低

缺點

  1. 侵入性高,在全部地方都須要引用。
  2. 仍是沒有辦法覆蓋全部的機型分辨率,部分機型可能適配效果仍是不佳
  3. 不能以高度爲基準進行適配
  4. 生成不少文件,增大APP體積1~2M

1.3 今日頭條適配方案

今日頭條屏幕適配方案的核心原理在於,根據如下公式算出 density

默認px = density * dp,也就是屏幕總寬度dp = 屏幕寬度px / density,這個時候咱們假設全部設備上的屏幕總寬度dp會等於咱們設計圖375dp,那麼能夠得出一個公式:

density = 屏幕寬度px / 設計圖寬度(375dp)

而後咱們經過系統api,將density賦值給系統,拋棄掉系統默認計算density的計算公式。

這樣能夠很巧妙的實現屏幕適配,並且侵入性極低,甚至能夠忽略不計。

驗證方案

1920 * 1080分辨率的手機,咱們一樣設置一個View爲187dp寬,設計圖寬度爲375dp

  • density = (屏幕寬度px = 1080) / 375 = 2.88
  • View寬度 = density * 187dp = 538.56
  • 算出佔屏幕寬度的比例,57.6 / 1080 = 0.498

1440 * 2560分辨率的手機,咱們一樣設置一個View爲187dp寬,設計圖寬度爲375dp

  • density = (屏幕寬度px = 1440) / 375 =3.84
  • View寬度 = density * 187dp = 718.08
  • 算出佔屏幕寬度的比例,718.08 / 1440 = 0.498

能夠看出,這種方案是徹底沒有偏差的,並且侵入性極低,只須要修改系統的density。雖然修改系統的density屬性會產生一小部分影響,可是基本都是很好解決的。

優勢

  1. 使用成本很是低,操做很是簡單
  2. 侵入性很是低
  3. 可適配三方庫的控件和系統的控件

缺點

  1. 會全局影響APP的控件大小,例如一些第三方庫控件,他們設計的時候可能設計圖尺寸並非像咱們同樣是375dp,這樣就會致使控件大小變形等一些問題。

參考文章

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

Android 屏幕適配終結者

Android 目前最穩定和高效的UI適配方案

相關文章
相關標籤/搜索