先放结论:
dp单位解决了同尺寸不同分辨率下,保持显示比例一致smallestWidth的多文件方案解决了同分辨率不同尺寸下,保持显示比例一致首选今日头条方案
前言:px有什么问题?
Android屏幕适配由来已久,关键在于屏幕尺寸与屏幕分辨率的变化巨大。在成千上百种机型面前,px单位已难以适应。
1.同样尺寸,不同分辨率: 1080px的宽度上显示100px 比例是100/1080 720px的宽度上显示100px 比例是100/720 2.同分辨率,不同尺寸: 1080px在4.7寸上显示100px 1080px在6.1寸上显示100px 如果使用多套px文件方案来适配,市面上少说上百种寸,需要的文件太多了。
第一个问题:同样尺寸但是不同分辨率的屏幕该如何适配?
dp是什么?
px:像素单位,1px代表1个像素
dpi:像素密度,单位英寸上的像素数量,公式是dpi=屏幕对角线像素总数px/屏幕对角线长度in
density:屏幕密度,规定以160dpi的屏幕其屏幕密度为1,反过来说就是屏幕密度为1的屏幕上1in上有160px
480 dpi/160 = 3 320 dpi/160 = 2 240 dpi/160 = 1.5 160 dpi/160 = 1 120 dpi/120 = 0.75
dp:Android开发上的基于屏幕密度的一种密度无关的像素单位,1dp代表的像素长度=density * 1 px
480 dpi上1dp = 1 * 3 = 3px 320 dpi上1dp = 1 * 2 = 2px 240 dpi上1dp = 1 * 1.5 = 1.5px 160 dpi上1dp = 1 * 1 = 1px 120 dpi上1dp = 1 * 0.75 = 0.75px
dp解决了什么问题?
以上公式表示了,同样尺寸上不同分辨率(不同density)的设备,每1dp所代表的像素数量是不一样的。
但是所表示的物理长度(160dp=1in)是一样的。
160 dp在density=3上表示480px,物理长度为1 in 160 dp在density=2上表示320px,物理长度为1 in 160 dp在density=1.5上表示240px,物理长度为1 in 160 dp在density=1上表示160px,物理长度为1 in 160 dp在density=0.75上表示120px,物理长度为1 in
至此,dp单位的使用就意味着你在这些同样尺寸但是不同分辨率的设备上看到的大小一样,此时各设备上显示的比例也就一致了。
dp没有解决什么问题?
同样分辨率(相同的density)但是尺寸不同的设备上,dp会显示出什么样的效果呢?这里要算一下每个设备上的总dp,以横向举例:
同样是480 dpi的像素密度,但是尺寸不同的设备: density=3,1080px/(480dpi/160) = 360 dp density=3,720px/(480dpi/160) = 240 dp 同样是320 dpi的像素密度,但是尺寸不同的设备: density=2,1080px/(320dpi/160) = 540 dp density=2,720px/(320dpi/160) = 360 dp 同样是240 dpi的像素密度,但是尺寸不同的设备: density=1.5,1080px/(240dpi/160) = 720 dp density=1.5,720px/(240dpi/160) = 480 dp
这种情形下面,有的大屏,有的小屏,各种屏幕的总dp不一样,dp单位也无法完成适配了。啊哈?那这就跟px的弱点一样的啊?没错就是酱紫~
在dp之上的补充方案
Android3.2之后提供了smallestWidth最小宽度限定符方案:
多套dp文件,文件仍然需要多套,但是比起px会少很多~
不需要与分辨率完全匹配,可以找到差距最小的文件,比起px容错率更高~
并且同时可以使用sp适配文字,比px好~
今日头条方案
代码中动态替换density大小~,不需要多套文件了~
所以首选这个方案!!!
Github链接:
理解了这些,再也不用苦恼了哈哈哈
Google对像素密度划分区域

名称像素密度范围缩放倍数
ldpi~120dpi0.75
mdpi120dpi~160dpi1
hdpi160dpi~240dpi1.5
xhdpi240dpi~320dpi2
xxhdpi320dpi~480dpi3
xxxhdpi480dpi~640dpi4

Google官网链接:
PS:如果不小心碰到了非标准的方形像素的设备,那么,呃…嗯看起来就会扁了