闲话Android屏幕:尺寸、分辨率、像素密度解析

1 前言

与隔壁iOS不同枯燥乏味不同,Android设备屏幕可谓百花齐放,百家争鸣,上图是一个Android设备不同尺寸屏幕的一个分布示意。

  • 屏幕的尺寸不一样,6英寸,5.5英寸。
  • 屏幕的像素点数量不一样,7201080,10801920
  • 屏幕的像素密度不一样,每英寸里包含的像素的数量不一样。
  • 且尺寸和像素点没有必应点。

设计的时候,不可能给每一种规格的屏幕一一做设计,开发设计时如何去适配呢?

为了解决这个问题,我们要先明确一些概念。

2 屏幕规格

屏幕尺寸 指的物理上屏幕的大小,一般以英寸(inch)为单位,我们经常说的6英寸,8英寸,其实说的是屏幕的对角线以英文为单位的长度。

分辨率 指的是屏幕的像素点的数量,比如1920*1080表示屏幕纵向上有1920个像素点(px),横向上有1080个像素点(px)

ppi 指的是每英寸长度内里包含里的像素点的数量。这个指标在手机上通常的计算规则是屏幕对角线的像素个数除以对角线的英寸得到。

明确了这些概率以后,我们举一个例子,以遥遥领先p60为例。

  • 屏幕的物理尺寸,我们平时说的x英寸,屏幕对角线的长度为6.67英寸,宽度为2.75英寸,高度为6.1英寸。
  • 屏幕分辨率,1220px * 2700px
  • 屏幕像素密度(ppi),通过ppi的定义,我们在已知道,横向和纵向的像素点以及斜边的英寸尺寸时,可以用以下公式计算出屏幕的 PPI = <math xmlns="http://www.w3.org/1998/Math/MathML"> ( 宽 p x ) 2 ) + ( 高 p x ) 2 ) / 斜边 i n c h \sqrt{\smash[b]{ \left(宽px)^{\smash{2}}\right) + \left(高px)^{\smash{2}}\right)}} /斜边inch </math>(宽px)2) + (高px)2) /斜边inch。最终得到该设备的 ppi约为444
机型 宽度(px) 高度(px) 斜边(px) 宽度(inch) 高度(inch) 像素密度
华为p60 1220 px 2700 px 2964 px 2.75 inch 6.67inch 444ppi

3 相对单位

3.1 Android

dp(density-independent pixels)

A dp is equal to one physical pixel on a screen with a density of 160.

在Android系统中,规定了一个相对单位dp(density-independent pixels),1inch = 160dp, 是一种与像素无关的单位。

这就意味着,1dp在像素密度为160的屏幕上代表1px。依此类推,在像素密度为320的屏幕上,1dp为2px,在480dp的屏幕上,1dp为3px。

使用dp是为了解决什么问题呢?

使用dp作为度量保证在不同规格的屏幕上表达的真实物理长度是一样的

举个例子:

有如上两种显示规格的屏幕,使用dp单位,显示的真实物理的宽度是一样的。

这里再引入一个概念density,px = density * dp,这样我们就可以很方便在dp和px之间进行换算。

为了加深印象,稍微总结一下这几个概念的关系

  • ppi = <math xmlns="http://www.w3.org/1998/Math/MathML"> ( 宽 p x ) 2 ) + ( 高 p x ) 2 ) / 斜边 i n c h \sqrt{\smash[b]{ \left(宽px)^{\smash{2}}\right) + \left(高px)^{\smash{2}}\right)}} /斜边inch </math>(宽px)2) + (高px)2) /斜边inch
  • 160 px = 1 inch
  • inch = px / ppi
  • density = ppi /160
  • px = density * dp

有了上面的知识,在已知屏幕分辨率(eg:1080px * 1920 px)和英寸(6.0 inch)的情况下,我们能比较容易的得到下面所有的数据信息,还是以上面这两种规格屏幕为例,得到以下数据。

宽度(px) 宽度(px) 斜边(px) 宽度(inch) 高度(inch) 斜边(inch) ppi 宽度(dp) 高度(dp)
机型1 2700 2700 2960 2.75 6.1 6.67 443 439 973
机型2 720 1280 1468 2.45 4.4 5.0 293 392 697

3.2 iOS

iOS 中也有类似的机制,以保证在不同规格屏幕上使用某个度量达到表示相同物理尺寸的目的,iOS规定了pt这种相对单位。与Android中 1 inch = 160 pt 不同的是,在iOS中规定,1 inch = 163pt

4 图片显示

在Android工程项目里我们会在drawable,drawable-hdpi,drawable-xhdpi,drawable-xxhdpi,drawable-xxhdpi等不同的文件夹下放置图片。在Android中不同文件夹下面的文件,有什么机制保证加载到适合屏幕像素密度的图片呢?

首先Android系统中会把屏幕根据其像素密度做一个大致的分类,低密度、中密度、高密度、超高密度、超超高密度..

密度限定符 说明
drawable-ldpi 适用于低密度 (ldpi) 屏幕 (~ 120dpi) 的资源。
drawable-mdpi 适用于中密度 (mdpi) 屏幕 (~ 160dpi) 的资源(这是基准密度)。
drawable-hdpi 适用于高密度 (hdpi) 屏幕 (~ 240dpi) 的资源。
drawable-xhdpi 适用于加高 (xhdpi) 密度屏幕 (~ 320dpi) 的资源。
drawable-xxhdpi 适用于超超高密度 (xxhdpi) 屏幕 (~ 480dpi) 的资源。
drawable-xxxhdpi 适用于超超超高密度 (xxxhdpi) 屏幕 (~ 640dpi) 的资源。

正常我们使用根据图片ID加载图片的时候,系统会寻找与我们屏幕密度接近的dpi,然后再根据屏幕密度和加载的图片的指定密度做一个缩放得到一个适当的屏幕密度。

举个例子当前屏幕密度(ppi)为443。那么就会在xxhdpi文件夹下查找,如果不存在,再往xxxhdpi里寻找,如果xxxhdpi也不存在,就在xxhdpi查找,如果此时找到了,那么我们定义加载到的这张图片的inDensity为320。我们屏幕的密度为443,那么系统会把加载到的图片做一个放大,放大的比例为443/320。

这里稍微扩展一下,关于图片大小的问题。上面我们更多的是讨论的图片尺寸维度的大小。还有另外一个维度占用存储空间的大小,我们平时所说的某张图片20KB,8M。在占用存储空间这个维度,其实又分为两个层面。

  • 内存占用
  • 静态(传输)占用

内存占用大小和传输占用大小没有必然的关系。一张图片在内存中占的大小的计算公式为:长度x宽度x一个元素所占大小。其中一个元素所占的大小和色彩模式有关。如argb8888模式占32bit也就是4个字节,rgb655占16bit也就是2字节,使用合适的色彩是我们做图片优化的重要手段之一。

静态占用 个人理解静态占用为了描述图片信息所占用的空间大小 举个例子,我们下载一张2M的png格式大小的图片,在内存中的最终的占用还说要使用上面的公式(长度x宽度x所占大小)。

5.结

本文主要是梳理屏幕规格的概念屏幕的尺寸,分辨率、像素密度,以及他们之间的关系。相信明确了这些理解了这些之后,我们通常所说的设计稿里的尺寸怎么转换成开发的尺寸,屏幕碎屏化的问题解决方案这些问题都会很容易理解搞懂。

相关推荐
Myli_ing14 分钟前
考研倒计时-配色+1
前端·javascript·考研
大白要努力!14 分钟前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
余道各努力,千里自同风16 分钟前
前端 vue 如何区分开发环境
前端·javascript·vue.js
软件小伟25 分钟前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾1 小时前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧1 小时前
TypeScript 的发展与基本语法
前端·javascript·typescript
hummhumm1 小时前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
天空中的野鸟1 小时前
Android音频采集
android·音视频
asleep7011 小时前
第8章利用CSS制作导航菜单
前端·css
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架