关于dpi 屏幕密度的总结

时间:2021-7-4 作者:qvyue

一、几个概念

1.1、分辨率:分辨率就是手机屏幕的像素点数,一般描述成屏幕的“宽×高”。

1.2、屏幕大小:屏幕大小是手机对角线的物理尺寸,以英寸(inch)为单位。

1.3、密度(dpi,dots per inch;或PPI,pixels per inch)

从英文顾名思义,就是每英寸的像素点数,数值越高当然显示越细腻。

dpi = 屏幕对角线上的像素点数/对角线的物理尺寸(inch)

关于dpi 屏幕密度的总结
image

实际密度与系统密度

1.3.1、“实际密度”就是我们自己算出来的密度,这个密度代表了屏幕真实的细腻程度。如上述例子中的440dpi就是实际密度

1.3.2、系统密度:每部安卓手机屏幕都有一个初始的固定密度,这些数值是120、160、240、320、480,我们权且称为“系统密度”

安卓对界面元素进行缩放的比例依据正是系统密度,而不是实际密度

drwable dpi density 分辨率
ldpi 120dpi 0.75 240*320px
mdpi 160dpi 1 320*480px
hdpi 240dpi 1.5 480*800px
xhdpi 320dpi 2 720*1280px
xxhdpi 480dp 3 1080*1920px

dp 与px

dp (或dip density-independent) 旨在保证不同密度的屏幕上,显示的相对物理尺寸是一直的。举个例子。A和B是两款不同屏幕密度的手机,他们的物理尺寸(长和宽)一致,dp绘制图像,可以保证无论A和B的屏幕密度是多少,在A和B两款手机上显示的物理尺寸是一样的。

dp的官方说明:

A virtual pixel unit that you should use when defining UI layout, to express layout dimensions or position in a density-independent way.
  The density-independent pixel is equivalent to one physical pixel on a 160 dpi screen, which is the baseline density assumed by the system for a “medium” density screen. At runtime, the system transparently handles any scaling of the dp units, as necessary, based on the actual density of the screen in use. The conversion of dp units to screen pixels is simple: px = dp * (dpi / 160). For example, on a 240 dpi screen, 1 dp equals 1.5 physical pixels. You should always use dp units when defining your application’s UI, to ensure proper display of your UI on screens with different densities.

px = dp * (dpi / 160)

简单来说,以160dpi的设备为准,该设备上1dp = 1px。如果屏幕密度大,1dip代表的px就多,比如在320dpi的屏幕上,1dip=2px(即1dp代表2个像素)

二、Android系统寻址drawable图片的过程

Android 项目res中有多个drawable文件夹,如下图,在6个drawable文件夹下分别放置了同一张icon图片

drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi
drawable-xxxhdpi

2.1、app 在不同的屏幕密度的手机上是如何选择不同drawable文件夹下图片的?

当我们使用资源id来去引用一张图片时,Android会使用一些规则来去帮我们匹配最适合的图片。

什么叫最适合的图片?

比如我的手机屏幕密度是xxhdpi,那么drawable-xxhdpi文件夹下的图片就是最适合的图片。当我引用android_logo这张图时,如果drawable-xxhdpi文件夹下有这张图就会优先被使用,并且这张图片是不会被缩放的。如果drawable-xxhdpi文件夹下没有这张图时, 系统就会自动去其它文件夹下找这张图了,优先会去更高密度的文件夹下找这张图片。我们当前的场景就是drawable-xxxhdpi文件夹,然后发现这里也没有android_logo这张图,接下来会尝试再找更高密度的文件夹,发现没有更高密度的了,这个时候会去drawable-nodpi文件夹找这张图,发现也没有,那么就会去更低密度的文件夹下面找,依次是drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi。

所以寻址过程如下:

  • 根据系统屏幕密度,查找对应最理想的图片(假设最理想的是drwable-xhdpi)
  • 若理想dpi文件夹中图片不存在,则向高密度文件夹依次寻找(如xxhdpi->xxxhdpi)
  • 向上寻址无果,则尝试在drawable-nodpi(密度无关)中寻找
  • drawable-nodpi 寻址无果,则尝试向下寻址图片(hdpi->mdpi->ldpi)

    关于dpi 屏幕密度的总结
    drawable寻址

2.2、寻找到图片后,进行缩放操作

dpi范围-密度 表格

dpi范围 密度
0dpi ~ 120dpi ldpi
120dpi ~ 160dpi mdpi
160dpi ~ 240dpi hdpi
240dpi ~ 320dpi xhdpi
320dpi ~ 480dpi xxhdpi
480dpi ~ 640dpi xxxhdpi

每一种密度的dpi范围都有一个最大值,这个最大值之间的比例就是图片会被系统自动放大的比例。

假设手机的屏幕密度为320dpi,寻址ic_arrow的图片. 目标图片选址文件夹为drawable-xhdpi(2倍图)

  • 假设ic_arrow仅存放在了drawable-xxhdpi(3倍图)中,经过系统寻址后最终定位到drawable-xxhdpi中的图片。需要对图片进行等比缩小。
缩小比例 = 320(系统密度)/480(drawable-xxhdpi的密度) = 2/3
  • 假设ic_arrow图片保存在了drawable-hdpi(1.5倍图区域)中,经过系统寻址后定位到drwable-hdpi中的图片。需要对图片进行定比放大。
放大比例 = 320(系统密度)/240(drawable-hdpi的密度) = 4/3

三、非标准屏幕密度 是如何寻址drawable图片

在第二节中 这对标准屏幕(屏幕密度为120、160、240、320、480、640的屏幕),drawable图片的寻址和放缩过程 我们基本清楚了。Android手机的屏幕千千万万,那些非标准密度的屏幕,图片的寻址和放缩规则也一样吗?

答案是肯定的。

针对标准密度屏幕和非标准密度屏幕。

3.1、图片寻址规则:

以Android手机屏幕的系统密度为基准,优先向上寻址;
寻址到最高的dpi仍未命名图片,则依次向下寻址,直至命中图片

3.2、图片的放缩规则:

图片放缩比例 = 系统密度/最终选址drawable文件夹代表的图片密度

假设 系统密度为440dpi,系统最终选址命中的图片文件夹为drawable-xxhdpi(代表480dpi)

则命中图片的放缩倍数 = 440/480
假设drawable-xxhdpi中图片的宽度为143,则放缩之后图片宽度为143*440/480=131

drwable dpi density 分辨率
ldpi 120dpi 0.75 240*320px
mdpi 160dpi 1 320*480px
hdpi 240dpi 1.5 480*800px
xhdpi 320dpi 2 720*1280px
xxhdpi 480dp 3 1080*1920px

四、Android项目中 应该保存几份drawable-dpi文件

Google建议 为主流的机型尽量都做一套适配图片,这样UI显示效果最佳。

4.1、那问题来了,主流的屏幕密度是什么样的?

我没有找到2021年最新的统计数据,但找到了2018年的一份统计数据

统计数据显示 2018年主流的屏幕密度为xhdpi和xxhdpi,按照国内Android手机的更新换代频率推测,2021年 xxhpi应该已经成为主流的屏幕密度(480dpi)

关于dpi 屏幕密度的总结
image

关于dpi 屏幕密度的总结
image

4.2、国内优秀app是怎么做的?

我查看了微信、快手、今日头条、知乎等几款Android app,解压查看res文件夹下drawable适配情况,如下:

应用 dpi分布 主要dpi
微信 mdpi(102)、hdpi(588)、xhdpi(237)、xxhdpi(1044)、xxxdpi(104) xxhdp
快手 hdpi(99)、mdpi(299)、xhdpi(346)、xxhdpi(6338)、xxxhdpi(279) xxhdpi
今日头条 hdpi(3)、xhdpi(1886)、xxhdpi(784)、xxxhdpi(34) xhdpi
知乎 xhdpi(133)、xxhdpi(1723)、xxxhdpi(47 xxhdpi

除了今日头条以xhdp为未主要适配对象,其他都重点适配了xxhdpi。

所以最终结论是:

Android手机app 仅适配一个主流屏幕密度即可(目前为止为xxhdpi),其他的屏幕密度依靠Android系统的图片寻址和放缩机制自动适配即可。

五、参考文章

https://www.jianshu.com/p/b3b67fd8aa24?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weixin-friends

https://blog.csdn.net/bencheng06/article/details/84582065

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。