1.基本概念
1.1 px
簡單說,像素就是表示一個點的RGB顏色陆错;這個點灯抛,是數(shù)學上的概念,是沒有大小的音瓷;但是屏幕顯示一個像素是需要大小的对嚼,具體大小是屏幕尺寸除以屏幕分辨率
1.2 屏幕分辨率
屏幕分辨率就是屏幕最多能顯示多少個像素绳慎,如果屏幕最多能顯示1080 * 1920個像素杏愤,屏幕大小是3 * 5英寸的珊楼,那么每個像素占用(3/1080) * (5/1920)的大小。一般情況下屏幕寬高比和像素寬高比是相等的画舌,
1.2 ppi, dpi
屏幕上每英寸上點的數(shù)量,我們叫做DPI(dots per inch),因為屏幕上面每個點對應一個像素句葵,所以也有叫PPI兢仰;兩者大部分情況可以混用,有時候又不一樣轻专。當DPI小的時候请垛,每個點的物理尺寸就變大(點的大小理解為 DPI 分之一 英寸宗收;比如DPI是160亚兄,每個點就是 1/160 英寸)审胚;所以要解決屏幕顆粒大的問題,提高DPI值就可以了洽洁。但DPI提高后诡挂,又出現(xiàn)了另外一個問題:同樣像素的Bitmap在新的屏幕上看起來小了璃俗。假設把DPI從160提高到320悉默,原來160像素在新屏幕上的大小只有原來的一半抄课。
1.3 dp,sp
- 因為在不同dpi下,相同像素下長度不一樣攒盈,android引入了dp(density independent pixel)哎榴,sp(Scale-independent Pixel)作為長度單位尚蝌。簡單粗暴直接規(guī)定一英寸就是160dp飘言,即1dp=1/160inch;android內部幫我們做了1dp對應多少像素的換算姿鸿,即(px=dp*(dpi/160)),即1dp在dpi為160的設備上對應1px,在320dpi上對應2px纪铺。如此保證在相同dp下鲜锚,在不同屏幕密度下顯示一樣的長度苫拍。
- sp和dp很類似但唯一的區(qū)別是绒极,Android系統(tǒng)允許用戶自定義文字尺寸大小(小榔袋、正常铡俐、大审丘、超大等等),當文字尺寸是“正巢ゼ保”時桩警,1sp=1dp=1/160inch昌妹,而當文字尺寸是“大”或“超大”時柱蟀,1sp=1sp*scale>1/160inch蚜厉。類似我們在windows里調整字體尺寸以后的效果——窗口大小不變昼牛,只有文字大小改變贰健。
1.3.1 dp的缺陷
- dp解決了大小一致的問題伶椿,沒解決比列的問題脊另;如果我們設定控件的寬是160dp偎痛,在寬是3inch的屏幕上占比是1/3,在寬是4inch的屏幕上占比是1/4踩麦。
- 不精確谓谦;android會將實際dpi進行修正 然后根據density=dpi/160算出density贪婉,而px=density * dp星压;由此可知不是精確的,因為會修正娜膘。如實際屏幕密度為321dpi,參考下表知修正后的dpi為480军洼,density為3匕争。
名稱 代表分辨率 范圍 修正 density mdpi 320x480 120dpi~160dpi 160dpi 1 hdpi 480x800 160dpi~240dpi 240dpi 1.5 xhdpi 720x1280 240dpi~320dpi 320dpi 2 xxhdpi 1080x1920 320dpi~480dpi 480dpi 3 xxxhdpi 480dpi~640dpi 640dp 4 - 和美工的設計搞不對應。如設計師的圖片基準是1080 * 1920歹叮,單位是px德谅,如果圖標是60px*60px窄做,我們不能直接寫60dp * 60dp椭盏,要根據屏幕密度換算成相應的dp庸汗。
2.寬高限定符適配
2.1好處
寬高限定符解決了比列蚯舱,不精確和 美工設計稿不對應三大問題枉昏。
2.2使用
做法就是窮舉市面上所有的Android手機的寬高像素值:
設定一個基準的分辨率兄裂,其他分辨率都根據這個基準分辨率來計算,在不同的尺寸文件夾內部,根據該尺寸編寫對應的dimens文件晰奖。
比如以480x320為基準分辨率
寬度為320谈撒,將任何分辨率的寬度整分為320份,取值為x1-x320
高度為480匾南,將任何分辨率的高度整分為480份啃匿,取值為y1-y480
那么對于800480的分辨率的dimens文件來說,
x1=(480/320)1=1.5px
x2=(480/320)*2=3px
這個時候蛆楞,如果我們的UI設計界面使用的就是基準分辨率溯乒,那么我們就可以按照設計稿上的尺寸填寫相對應的dimens引用了,而當APP運行在不同分辨率的手機中時,這些系統(tǒng)會根據這些dimens引用去該分辨率的文件夾下面尋找對應的值豹爹。這樣基本解決了我們的適配問題裆悄,而且極大的提升了我們UI開發(fā)的效率逻住,
2.3缺陷
- 需要精準命中才能適配吁恍,比如1920x1080的手機就一定要找到1920x1080的限定符,否則就只能用統(tǒng)一的默認的dimens文件了。而使用默認的尺寸的話尼啡,UI就很可能變形书聚,簡單說萨驶,就是容錯機制很差。
- 不適用于sp,當更改系統(tǒng)的字體大小時,字體大小不會改變灭贷。因為本質上還是用的px。
- 包體積大。因為市面上不同寬高的屏幕很多,這里盡可能的適配所有的話,會增大包的體積鹅搪,采用這種方式包體積一般增大400kb~500kb
3.代碼適配
3.1基本原理
3.2常用的百分比庫
android-support-percent android官方的現(xiàn)已經棄用
[AndroidAutoLayout]
(https://github.com/hongyangAndroid/AndroidAutoLayout)鴻洋的 已停止維護
上面兩個庫都已經停止維護坠非,現(xiàn)在推薦用ConstraintLayout替代潦闲。
3.3缺陷
- 第三方的控件無效
- 老項目更改繁瑣
- 設計圖不匹配
4.最小寬度限定符
4.1 好處
- 解決了比列
- 教精確 如果有對應不上的情況和敬,會向下找蚕键,這樣的話失去了一部分精確性
- 對應美工設計稿铝耻。因為將屏幕分成美工給定的等分
4.2 使用
smallestWidth適配,或者叫sw限定符適配桐汤。指的是Android會識別屏幕可用高度和寬度的最小尺寸的dp值(其實就是手機的寬度值),然后根據識別到的結果去資源文件中尋找對應限定符的文件夾下的資源文件。
這種機制和上文提到的寬高限定符適配原理上是一樣的蚁滋,都是系統(tǒng)通過特定的規(guī)則來選擇對應的文件副女。
舉個例子,小米5的dpi是480,橫向像素是1080px裹赴,根據px=dp(dpi/160)诀浪,橫向的dp值是1080/(480/160),也就是360dp,系統(tǒng)就會去尋找是否存在value-sw360dp的文件夾以及對應的資源文件。
smallestWidth限定符適配和寬高限定符適配最大的區(qū)別在于幽污,前者有很好的容錯機制准潭,如果沒有value-sw360dp文件夾腻豌,系統(tǒng)會向下尋找苏携,比如離360dp最近的只有value-sw350dp,那么Android就會選擇value-sw350dp文件夾下面的資源文件析苫。這個特性就完美的解決了上文提到的寬高限定符的容錯問題兜叨。
這套方案是上述幾種方案中最接近完美的方案。
首先衩侥,從開發(fā)效率上,它不遜色于上述任意一種方案矛物。根據固定的放縮比例茫死,我們基本可以按照UI設計的尺寸不假思索的填寫對應的dimens引用。
我們還是以375個像素寬度的設計稿為例履羞,在values-sw360dp文件夾下的diemns文件應該怎么編寫呢峦萎?這個文件夾下屡久,意味著手機的最小寬度的dp值是360,我們把360dp等分成375等份爱榔,每一個設計稿中的像素被环,大概代表smallestWidth值為360dp的手機中的0.96dp,那么接下來的事情就很簡單了详幽,假如設計稿上出現(xiàn)了一個10px*10px的ImageView,那么筛欢,我們就可以不假思索的在layout文件中寫下對應的尺寸。
而這種diemns引用唇聘,在不同的values-sw<N>dp文件夾下的數(shù)值是不同的版姑,比如values-sw360dp和values-sw400dp,
當系統(tǒng)識別到手機的smallestWidth值時,就會自動去尋找和目標數(shù)據最近的資源文件的尺寸迟郎。
其次剥险,從穩(wěn)定性上,它也優(yōu)于上述方案宪肖。原生的dp適配可能會碰到Pixel 2這種有些特別的手機需要單獨適配表制,但是在smallestWidth適配中,通過計算Pixel 2手機的的smallestWidth的值是411控乾,我們只需要生成一個values-sw411dp(或者取整生成values-sw410dp也沒問題)就能解決問題夫凸。
smallestWidth的適配機制由系統(tǒng)保證,我們只需要針對這套規(guī)則生成對應的資源文件即可阱持,不會出現(xiàn)什么難以解決的問題夭拌,也根本不會影響我們的業(yè)務邏輯代碼,而且只要我們生成的資源文件分布合理衷咽,鸽扁,即使對應的smallestWidth值沒有找到完全對應的資源文件,它也能向下兼容镶骗,尋找最接近的資源文件桶现。
4.3 缺陷
- 不適配android3.2一下版本。其是android3.2以后引入的
- 包體積過大鼎姊。大約會增大300kb到800kb左右
5.density適配
今日頭條開放出來的方案
5.1優(yōu)點
- 解決比列問題
- 解決設計圖匹配問題
- 很精確
- 不影響包體積
5.2使用
5.2.1原理
從dp和px的轉換公式 :px = dp * density 可以看出骡和,如果設計圖寬為360dp,想要保證在所有設備計算得出的px值都正好是屏幕寬度的話相寇,我們只能修改 density 的值:
5.3缺陷
- 如果有用到第三方庫控件慰于,則不適用。因為修改了系統(tǒng)的density值之后唤衫,整個布局的實際尺寸都會發(fā)生改變婆赠。
6.其它(待更新)
參考:
Android 屏幕適配方案
一種極低成本的Android屏幕適配方式
Android 目前最穩(wěn)定和高效的UI適配方案