引子
屏幕適配是 android 開發/面試 繞不開的一個問題。本文 將屏幕適配的
知識要點
完整展現給各位讀者。
正文大綱
- android需要做屏幕適配的原因
- 基礎知識點(很重要)
- 屏幕適配攻略
正文
android需要做屏幕適配的原因
關鍵字:android碎片化
android面世以來,google開源了android系統,各家廠商各自爲政,導致屏幕尺寸沒有統一標準,屏幕的寬高比各種各樣,屏幕密度也是各個廠家攀比的資本, 導致Android開發者想要用一套代碼來適配所有的設備變得格外的困難,雖然 谷歌出了 dp單位來替代px,但是 dp依然有它無法完全適配的地方。
這個也就是需要我們利用其他手段去 完成適配的地方。
面試點
Q: 關於屏幕適配,爲什麼 有了
dp
單位,依然要適配呢?
A:dp
雖然能夠解決大部分情況下的適配問題,但是針對少數機型,無法適配,
原因 是:dp
單位,在現有的android
市場環境下,是不可靠
的,編碼時的dp
,在運行時會轉化成px
,此時的px不能準確對照UI的原本設計。
最直觀體現就是: 同樣300dp
,在A手機上可以佔滿全寬,但是在B手機上,佔不滿,或者會超出全寬。至於爲什麼dp不可靠?
後面會解釋。
基礎知識點(很重要)
以下概念很基礎,但是也很重要,基礎知識缺少一個環節,後面複雜的攻略理解起來就有障礙。
1. 像素點
像素點是物理概念,用術語來解釋,就是如下這段話:
通常所說的像素,就是CCD/CMOS上光電感應元件的數量,一個感光元件經過感光,光電信號轉換,A/D轉換等步驟以後,在輸出的照片上就形成一個點,我們如果把影像放大數倍,會發現這些連續色調其實是由許多色彩相近的小方點所組成,這些小方點就是構成影像的最小單位“像素”(Pixel)。簡而言之,像素就是手機屏幕的最小構成單元。
簡單來說,像素點就是屏幕上色彩區域的最小單位
。在所有的設備上,1px 都是等同的。UI小姐姐作圖一般都會以px爲單位。
2. 分辨率
比如:19201080 分辨率,表示當前設備的屏幕是由 橫向1080 縱向1920 個像素點 組合而成。
3. 屏幕尺寸
屏幕對角線的長度。 一般以英寸爲單位,常見的屏幕尺寸有
4.7
,5.5
,6.0
。
4. 屏幕像素密度
定義:
一平方英寸
面積內,存在多少個
像素點。
同樣是1920*1080
的分辨率,存在兩款手機,一個是4.7英寸,一個是6.0英寸,這兩者的像素密度
是不一樣的。
屏幕密度的單位: dpi(dots per inch).
標準屏幕分辨率 :160dpi 。即:一平方英寸
面積,存在160
像素點。(mdpi).
5. 屏幕尺寸,分辨率,像素密度 三者之間的關係
像素密度
,可以由屏幕尺寸
和分辨率
計算得出。
計算公式爲:
比如下圖所示:我這裏有一塊1920*1080的5寸屏幕,通過上面的公式計算得出,它的像素密度爲 440dpi .
可見,px是和像素密度有直接關係的 像素單位。
5. 密度無關的像素單位(dp,或者dip)
全英文爲:density-independent pixel.
(注意此處是dip
,上面的像素密度是dpi
, 千萬不要因爲這個,在面試的時候出醜 )
使用dp作爲長度單位,可以保證在不同的屏幕像素密度的手機上顯示 很相似的效果。
比如: 使用480x800
的手機上,要畫一條長度爲一半屏幕寬的線條,我們可以設置線條的長度爲240px
,而在320x480
的屏幕上,我們只需要160px
,但是我們可以直接使用160dp
,來同時讓兩個屏幕上的這條線佔全寬的一半。
px和dp的換算公式爲:
px = dp * (dpi / 160)
公式解讀:
如果有一個屏幕密度爲 160dpi的手機,在它上面,1px=1dp;
而如果是 320dpi的手機,則 1px = 0.5dp.
簡而言之規律就是: 屏幕像素密度(dpi)越高的手機,1dp所代表的px就越多.
下面解釋爲什麼dp有時候靠不住.
如果UI小姐姐以
320*480
dpi160
的屏幕爲標準,畫了一條長度爲160px
的線,長度爲屏幕寬度的一半
,這個時候,你直接用160dp
,一般就能完成適配。但是如果這樣的佈局 運行在320x480
分辨率,但是屏幕密度爲150dpi
略小於160dpi
,這個時候 你佈局裏面寫的160dp
就會實際超過160px
不再是佔屏幕寬的一半,而是略微超過。
6. 獨立比例像素 (sp)
全英文爲: scale-independent pixel (簡稱sp或者sip)
專門用於字體大小表示。
推薦使用12sp
以上的偶數作爲 字體大小, 不要使用奇數,或者浮點型小數,因爲容易造成精度丟失。
面試點
Q: sp和dp有什麼區別?
A: 通常情況下,dp和sp效果類似,但是有一點,如果用戶 調整了手機字體,比如 從標準,變成了 超大,那麼,1dp 原本等於1px依然不變,但是1sp就會從1px變成3px(只是舉個例子,數值不必認真).
因此,在用戶調整字體的情況下,同樣的佈局,可能出現 窗口大小不變,但是文字尺寸發生變化的情況。
屏幕適配攻略
1. 佈局適配
使用多套佈局適應不同屏幕。此方法必須要了解
佈局限定符
的概念。
如圖:
限定符: 在原本的layout
後面加上橫槓,然後加上限定名。形成 layout-XXX的形式,具體規則請參考谷歌官網: https://developer.android.google.cn/training/multiscreen/screensizes, 重點摘錄如下:
使用上面的限定符,幾乎可以解決所有的適配問題,但是另外還有一個小技巧幫我們節省工作量 :佈局別名.
適用情形爲:當多個加了限定符的 layout.xml中都引用了同一個 子佈局,而子佈局的內容可能相同,也可能不同。
這個時候,使用佈局別名,可以節省操作量。
方案評價: 講道理,這個是
下下策
,因爲在你需要修改佈局的時候,你可能需要修改多套佈局,這個要多噁心就多噁心,懂的人都懂.
2 代碼適配
我們通過java代碼去獲取屏幕的寬高,動態去指定控件的寬高 。
代碼適配,一般用於動態創建 控件,或者自定義view自己繪製圖形的時候。
特別提一下接口適配:當你去向後臺請求圖片的時候,我們可以在參數中帶入屏幕的寬高,或者是控件的寬高,來獲取我們想要的圖片,在圖片返回之後直接就能顯示得最優,而不需要我們app代碼中多動手腳。
方案評價:這個比下下策稍微好一點,但是
控件大小
直接進入了代碼,還是讓代碼不夠雅觀.
3. 佈局組件的適配
儘量直接通過一套佈局解決所有的麻煩,這個就叫佈局組件的適配。這個是上上策.
包含如下手段:
- 使用像素密度無關的單位
dp sp
- 杜絕使用絕對佈局,多使用相對和線性佈局
- 多使用 wrap_content match_parent 以及線性佈局的權重
- 多用 minWidth minHeight,lines 等屬性
- 使用多套限定的 dimens中定義的尺寸
可能面試點
Q:同一個佈局文件中,我使用線性佈局和相對佈局都可以達成目的,那麼如何抉擇?
A: 使用相對佈局,很有可能出現 第一次測量"不滿意"的情況,從而會測量第二次。如果兩者都可以達成目的,並且兩者的佈局層級相同,並且線性佈局中沒有使用到權重
(權重可能也會觸發第二次測量
),此時,優先使用線性佈局。 除此之外,都選擇相對佈局。
結語
屏幕適配,工作中並不困難,但是面試多會問到。
現今主流的兩種完美適配方案,有頭條方案(直接變更DisplayMetrics中的density),以及 多套dimens適配方案,兩者各有千秋。
最後
如果你看到了這裏,覺得文章寫得不錯就給個讚唄!歡迎大家評論討論!如果你覺得那裏值得改進的,請給我留言。一定會認真查詢,修正不足,定期免費分享技術乾貨。喜歡的小夥伴可以關注一下哦。謝謝!