目前兩類比較主流的android屏幕適配

  前言:本文只是筆者在學習了部分優秀文章後寫的理解、歸納、總結,是哪些優秀文章呢?我們先熱烈鼓掌,恭迎大佬:
Android 目前穩定高效的UI適配方案
一種極低成本的Android屏幕適配方式。如果我理解能幫到你,那就再好不過了。

  android的碎片化使得每一個開發者不得不面對屏幕適配這一個問題,個人認爲,目前行業上比較流行的適配方案大體可以分爲兩類:

  一類是靜態適配,包括寬高限定符適配方案、最小寬度限定符適配方案,這類方案主要是預先儘可能多的在res目錄下定義不同分別率的dimens文件,APP運行時系統會自動根據目標設備的分辨率找到對應分別率下的dimens文件,根據此文件下對應的值渲染控件的大小,所以可以看做靜態適配。Android 目前穩定高效的UI適配方案這篇文章對這類方案做了比較詳細的講解, 推薦看看。

  另一類就是動態適配了,代表方案就是今日頭條團隊開源的一種極低成本的Android屏幕適配方式

  爲什麼會存在這兩類方案呢?在開始這個問題前,我們先看一個公式:

  • px = dp * (dpi / 160);

  我們可以簡單的認爲:

  • px是系統用的,系統以px爲單位畫出控件的大小;
  • dp是人用的,程序員以dp爲單位在佈局文件中設置控件的大小;
  • 當系統在渲染一個控件時,系統會將佈局文件中的dp值通過dpi轉化爲px值,再來畫控件,

  到這裏,我們可能會疑問了:爲什麼px就是系統用的,dp是人用的。其實,在佈局的時候,Android並不推薦我們使用px這個真實像素單位,因爲不同的手機之間,分辨率是不同的,比如一個96*96像素的控件在分辨率越來越高的手機上會在整體UI中看起來越來越小。如圖:
在這裏插入圖片描述
出現類似於上圖這樣這樣,整體的佈局效果可能會變形,所以px這個單位在佈局文件中是不推薦的。再來看看下面這段佈局文件中dp轉化的源碼:
在這裏插入圖片描述
  通過上面的源碼可見,如果是px值的話,系統就直接用這個值了,而如果是dp值的話,系統會根據設備的density來對dp值進行相應的縮減,這裏的density就是上述公式中的(dpi/160),所以上述公式也可形變如下:

  • px = dp * density

  由於不同分辨率下,dpi將會不同,比如:
在這裏插入圖片描述
  所以,佈局時,Android推薦使用dp作爲尺寸單位來適配UI,用dp會讓系統走一個dp值轉換爲目標設備px值的過程,通過這個過程,在分辨率較低的手機中,可能1dp=1px,而在分辨率較高的手機中,可能1dp=2px,這樣的話,一個96*96dp的控件,在不同的手機中就能表現出差不多的大小了。

  到此,我們上面討論的都是不同手機導致不同分別率下的適配,通過用dp值佈局可以解決90%的屏幕適配。下面我們來看看,相同分別率的設備,dpi值不同時的適配。

  綜上,我們現在知道碎片化的最主要原因就是這個變量dpi的計算規則了,這個dpi值叫做像素密度,通常情況下,一部手機的分辨率是寬x高,屏幕大小是以寸爲單位,理想情況下, dpi值可以通過如下公式計算獲取:

在這裏插入圖片描述
  舉個例子:屏幕分辨率爲:1920*1080,屏幕尺寸爲5吋的話,那麼dpi爲440。

在這裏插入圖片描述

  但現在問題是,不同的設備廠商,他不按這個規則來給出dpi,這就導致相同分辨率的設備,其dpi也可能不相同,比如Google 的Pixel2(19201080)的dpi是420而不是480,也就是說,在Pixel2中,1dp=2.625px,這樣會導致相同分辨率的手機中,這樣,一個100dp100dp的控件,在一般的1080P手機上,可能都是300px,而Pixel 2 中 ,就只有262.5px,這樣控件的實際大小會有所不同

  爲了更形象的展示,假設我們在佈局文件中把一個ImageView的寬度設置爲360dp,那麼在下面兩張圖中表現是不一樣的:

  圖一是1080P,480dpi的手機,圖二是1080P,420dpi的手機

在這裏插入圖片描述

在這裏插入圖片描述
  從上面的佈局中可以看到,同樣是1080P的手機,差異是比較明顯的。在這種情況下,我們的UI可能需要做一些微調甚至單獨適配。那麼上述兩類適配方案都是怎樣來進行適配的呢?

  要理解Android的屏幕適配,除了要理解上述提到的那個公式,我們還要明確一個事情,那就是屏幕適配,無非就是要解決兩個問題:1、不同手機,不同分別率的問題,2、相同分別率,dpi值不同的問題。 下面我們就圍繞這兩個問題來看看屏幕適配的發展歷史。先來看看靜態適配方案:

  寬高限定符適配

  簡單說,就是窮舉市面上所有的Android手機的寬高像素值,放到項目資源文件下。

  最小寬度限定符適配

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

  可見,靜態適配方案都是預先準備一套dimens資源文件供系統自行選擇,具體的原理拉丁吳老師已經做了很容易理解的解說,這裏不再贅述了。恭迎大佬:
Android 目前穩定高效的UI適配方案
當你沉浸在大佬的思緒中時,記得要注意理解並找到寬高限定符適配方案和sw限定符適配方案的區別哦!

  動態適配:今日頭條適配方案

  今日頭條適配方案我之所以歸爲動態適配,是因爲它主要是動態去修改系統界面的density值:density = 設備真實寬(單位px) / 360,接下來只需要把我們計算好的 density 在系統中修改下即可,代碼實現如下:
在這裏插入圖片描述
同時在 Activity#onCreate 方法中調用下。代碼比較簡單,也沒有涉及到系統非公開api的調用,因此理論上不會影響app穩定性。

  那麼,靜態適配方案和動態適配方案又有哪些區別呢?

  其實,無論哪種方案,px值都是通過如下公式計算的:

  • px = dp * density

  區別就是,靜態適配方案的density是通過dpi/160計算獲得,即:

  • px = dp * (dpi / 160)

它本質上還是用的設備的dpi,當前設備的dpi值在整個APP的生命週期中至始至終都是不變的,dpi的控制權是在設備廠商手裏的,他說是多少就是多少,然而市面上那麼多廠商,這就導致同一分別率下,dpi值不盡相同,density不盡相同,我們按一個分別率的設計稿來佈局後,不同手機下同一界面就要麼過大,要麼顯示不滿的適配問題。所以需要變的只是我們預先要提供的dimens資源種類。

  再來看看今日頭條適配方案,假設設計圖寬度是360dp,以寬維度來適配。那方案的density = 設備真實寬(單位px) / 360。不同於上面的靜態方案,今日頭條適配方案完全拋棄了dpi值這個變量,不被廠商牽着鼻子走,大有任你廠商風裏來雨裏去,我自巋然不動的意境(我就靜靜的看着你裝13)。

  我們可以這樣認爲,dpi值是主觀給予的(廠商定的),設備真實寬度(單位px)是客觀存在的(物理寬度),正是基於這兩個現實,纔有了這兩類適配方案的情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章