byhook / dimens-maker

屏幕适配生成工具

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

1.概述

Android发展至今,功能越来越多,越来越强大,不过碎片化的问题也是众所周知的越来越严重,如果是做大众应用,我相信屏幕适配肯定是我们不可回避的一个问题,当然了,网上的适配方案有很多,比如:

Google的百度比布局 AutoLayout Android适配方案

...等等,大家如果有兴趣,可以去看看。 本方案实际上是第三种方案的一个演进!!!

2.在谈论屏幕适配之前,首先要知道的几个概念

  • 物理像素点(px):代表的是手机的物理像素点。
  • 密度无关像素(dp):密度无关像素等于160dpi屏幕上的一个物理像素,这是系统的基线密度。
  • 屏幕密度(dpi):屏幕物理区域中的像素量,Android 将所有屏幕密度分组为六种通用密度: 低(ldpi)、中(mdpi)、高(hdpi)、超高(xhdpi)、超超高(xxhdpi)和超超超高(xxxhdpi)。
  • 分辨率:屏幕上物理像素的总数。添加对多种屏幕的支持时, 应用不会直接使用分辨率;而只应关注通用尺寸和密度组指定的屏幕 尺寸及密度。

而关于px,dp,dpi直接的关系,可以用下面一个公式概况:

px = dp * (dpi / 160)

好了,有了上面几个概念之后,再来看一张genymotion模拟器的图:

我们会发现同一个分辨率会对应不同的dpi,而不同的分辨率可能会对应同一个dpi

那我们在实际过程中,到底是如何适配呢?这个时候我们就要充分运用Android的特性了!

3.如何支持多种屏幕

通常在工作中设计师一般是不会管你的什么dp,px的通常只会给你一种标准的尺寸,可能是720x1280或者直接按照IOS的尺寸750x1334来给设计图标注,如果按不同的分辨率给不同的图片,素材这种方式不太现实,工作量大不说,也会给最终的安装包带来很大的体积。

例如:

设计师给的尺寸为750x1334的图纸,标注一个按钮宽度为375,那我们能直接写375px或者375dp吗?肯定不行!因为设计师希望的效果实际上是:按钮的宽度占据屏幕宽度的一半!

思考:

那么我们该如何实现在大部分屏幕(比如:720x1280,1080x1920 ...)上显示出宽度占有一半的效果?有的人可能会说用线性布局进行权重划分,我这里只是举的一个特例,实际情况会更多,难道都用线性布局?如果大家够仔细的话,会发现在新的Android Studio中新建工程res目录中会多出一个资源文件夹values-w820dp,这个就是屏幕尺寸的新配置限定符(在Android 3.2 中引入)

在Android 3.2之前,系统会按照如下进行匹配 https://github.com/byhook/dimens-maker

values-ldpi
values-mdpi
values-hdpi (API 8中新增)
values-xhdpi (API 16中新增)
....

而在Android 3.2之后,系统会优先按这个来匹配资源文件

values-w320dp
values-w360dp
values-w480dp
values-w600dp
....

如何计算上面的values-w820dp呢?官方的计算公式:

N = width / (dpi / 160)

即在分辨率为720x1280,屏幕密度为240dpi的手机上,在存在多个适配文件夹的情况下,系统会优先读取values-w(N=720/(240/160))dp里的适配数据,即values-w480dp中的适配数据。

实践:

那么在分辨率为720x1280,屏幕密度为240dpi的手机上,需要(375*(720/750)/(240/160))dp,即240dp才可以显示出宽度的一半 而在分辨率为720x1280,屏幕密度为320dpi的手机上,则需要 (375*(720/750)/(320/160))dp,即180dp才可以显示出宽度的一半!

用公式来描述一下:

记设计稿尺寸宽度为ow-oh,即750x1334中的750 记设计稿尺寸中标注的值为x,例子中标注的即为375 那我们实际要在分辨率为tw-th,屏幕密度为ndpi的手机中显示标注尺寸

result = x * (tw/ow) / (n/160)dp

有了上面的公式,那么剩下的工作就只有两个了:

1.根据设计稿生成对应的values-wNdp文件夹 2.在对应的文件夹里生成对应的dp适配数据

来看看最终的适配效果 设计稿尺寸为750x1334 宽度写上dimen_px_375的效果如下

不同屏幕密度的分布情况(可以看看DisplayMetrics里的声明):

类别 dpi 缩放比率 代表机型
ldpi 120 75% 已经被市场淘汰
mdpi 160 100% 基本被市场淘汰
tvdpi 213 133% Google Nexus 7
hdpi 240 150% Sumsong Glaxy S2, Google Nexus S, MOTO Droid
xhdpi 320 200% Sumsong Glaxy S3, Sumsong Note2, Google Nexus 4
xxhdpi 480 300% 目前市场上各品牌的旗舰机:Sumsong Glaxy S4、 Asus Padfone Infinite、HTC One、 小米3
xxxhdpi 640 400% 部分最新的旗舰机

优先级

原则上来说,dalvik优先使用符合设备dpi的资源,其次是dpi较低的高dpi资源,再次是dpi较高的高dpi资源,最后采用nodpi的资源,由此,根据设备自身的dpi的不同,不同dpi资源的优先级是有差异的(忽略mdpi&hdpi):

设备dpi 优先级顺序(由高到低)
tvdpi tvdpi>hdpi>xhdpi>xxhdpi>mdpi>default>ldpi>nodpi
hdpi hdpi>xhdpi>xxhdpi>tvdpi>mdpi>default>ldpi>nodpi
xhdpi xhdpi>xxhdpi>hdpi>tvdpi>mdpi>default>ldpi>nodpi
xxhdpi xxhdpi>xhdpi>hdpi>tvdpi>mdpi>default>ldpi>nodpi

###小结

日常开发过程中,尽量使用相对布局来控制位置,或者使用线性布局的weight属性来控制权重分布,还可以使用.9图来适配不同的拉伸情况,防止失真。

适配生成工具 https://github.com/byhook/dimens-maker

参考: 官方文档 https://developer.android.com/guide/practices/screens_support.html values-sw600dp文件标题的理解。

About

屏幕适配生成工具


Languages

Language:Java 100.0%