Android屏幕适配详解

刚做Android开发时就研究过屏幕适配的专题,后来只记得常用的那些东西,不常用的就忘了,等再要用的时候又要去查,这次把之前的研究总结一下,记录下来,方便以后查阅。

ppi、dpi、dp详解

1、ppi
Pixel per inch,每英寸像素数,表示显示设备的像素密度。

2、dpi
dot per inch,每英寸多少点,表示印刷品的印刷密度。针对显示设备时,dpi等同于ppi。

密度计算方法:假设屏幕4.0寸、分辨率800*480,所以该屏幕的dpi = 对角线像素点总数/4,根据勾股定理,即dpi=√(1920^2 + 1080^2)/4

3、dp
安卓开发专用单位,在160dpi屏幕上,1dp=1px,320dpi屏幕上,1dp=2px。

dp值代表的物理长度是固定的,比如:
屏幕3.0寸、分辨率300*400,对角线500px,大概是160dpi,1dp等于1px,物理长度大概是(1/500)*3.0
屏幕3.0寸、分辨率600*800,对角线1000px,大概是320dpi,1dp等于2px,物理长度大概是(2px/1000px)*3.0
屏幕6.0寸、分辨率300*400,对角线500px,大概是80dpi,1dp等于0.5px,物理长度大概是(0.5/500)*6.0

可以看出,无论屏幕大小、分辨率怎么变,dp对应的px值是随比例变化,px占屏幕的比例也是随比例变化,最终物理长度保持固定。

XXXdpi限定符

mdpi(160dpi)、hdpi(240dpi)、xhdpi(320dpi)、xxhdpi(480dpi)。。。这两种是一样的,但是谷歌限定了只能以80dpi为步进(res资源中出现xxx-180dpi文件夹就会报错),所以退出了m/h/xh/xxh等符号,来防止开发者使用其它数值。

匹配规则:如果一个屏幕为280dpi,优先去hdpi找对应的资源,如果没有hdpi资源文件夹或该文件夹下没有对应的资源,就去高一级的dpi资源下找,如果没有就继续往高一级找。最后还是没有找到,就去低一级找(即mdpi),最后还没找到就使用默认values资源,如果默认values资源下也没有,就报错。

使用规则:该限定符主要是使用在drawable资源上,因为dimen可以使用dp单位,在各种dpi下对应的物理尺寸都是一样的,而图片的单位是px,所以xxxdpi限定符主要应用与图片适配上。
对于mdpi的手机,会使用drawable-mdpi资源下的图片,但是如果没找到,就会使用其它hdpi资源下的图片,为了保证这种情况下的显示效果,有如下规则:
drawable-mdpi资源下的图片显示到mdpi手机上是原图显示,显示到hdpi手机上会把图片拉伸(240/160)倍后显示,显示到xhdpi手机上会拉伸(320/160)倍。。。依次类推;

drawable-xhdpi资源下的图片显示到xhdpi手机上是原图显示,显示到mdpi手机上会拉伸(160/320)倍,显示到hdpi手机上会拉伸(240/320)倍。。。依次类推。

swXXXdp限定符

使用dp值能保证不同屏幕下的物理尺寸是一致的,但是有两个缺点:1.dpi的步进是固定的,239dpi的屏幕,只能使用160dpi资源下的尺寸,效果很差;2.很多时候我们并不希望物理尺寸一致,而是希望跟随屏幕大小按比例改变。

使用values-sw300dp限定符,sw:small width的缩写,即短边宽度,不关注屏幕方向。该限定符可以指定任意数值的dp,步进为1dp。

对于手机app来说,大多数情况下,我们想要某个控件的宽度按屏幕宽度比例,这样可以保证左右两侧的空间都能完全显示。而高度却不需要,因为手机可以上下滑动的。

匹配规则:屏幕宽度dp值必须大于values-swXXXdp中的XXX值,取最接近的。

同一个dimen,在sw300dp下的值为30dp、sw350dp下的值为35dp、sw400dp下的值为40dp。。。。基本可以保证该dimen总是占屏幕的1/10左右,步进越小越精确。

1920x1080、1280x720限定符

但是某些情况下,需要尺寸完全精确地随屏幕宽高变化,就需要通过分辨率限定符了。比如values-1920x1080,指分辨率为1920*1080,1920和1080的顺序随意。同时有values-1920x1080和values-1080x1920资源会资源重复错误。

匹配规则:屏幕长边必须大于values-XXX*XXX中的长边,屏幕短边必须大于values-XXX*XXX中的短边,然后取最接近的。

使用这种限定符,dimen的值就要使用px了,比如你希望某个控件的宽、高均占屏幕宽、高的1/10,那么在values-1920x1080资源下width值就为108px、height值就为192px,在values-1280x720资源下就分别为72px、128px了。

这种限定符的优点是足够精确,缺点是需要维护的文件太多,目前主流的手机至少有十几种分辨率,每次增加一个dimen值,需要同步到十几个资源文件下。

对于有虚拟按键的手机,需要减去虚拟按键的高度,使用实际高度值。比如1920x1080的手机,如果带虚拟按键的话,实际高度是getWindowManager().getDefaultDisplay().getHeight(),而不是1920。

其他限定符

除了上面几种常用的限定符之外,还有很多没那么常用的限定符,而且它们是有优先级的。

所有限定符按优先级排列:mcc310(运营商)-en(语言)-sw320dp(小边宽度)-w720dp(最佳宽度)-h720dp(最佳高度)
-large(size)-long(长短屏模式)-port(横竖屏)-car(dock模式)-night(白天或夜晚)-ldpi(最佳dpi)-notouch(触摸屏模类型)

-keysexposed(键盘类型)-nokey(硬按键类型)-navexposed(方向键是否可用)-nonav(方向键类型)-v7(版本)。

优先级使用场景:有values-sw320dp、values-mdpi和values-1920x1080三个资源文件
只要机器满足sw320dp,就会选择sw320dp,不会去判断mdpi和1920c1080;如果不满足再判断是否满足mdpi;最后才会判断是否满足1920x1080。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值