基础概念
常见尺寸单位
-
mm
毫米,长度单位。` -
in(inch|″)
英寸,长度单位,1in=25.4mm
。 -
px(pixel)
像素,图像显示的基本单位。
密度单位
-
ppi(pixels per inch), px/in
密度单位,每英寸像素数。 -
dpi(dots per inch)
密度单位,每英寸能印刷的点数。
ppi 与 dpi 基本上等价。不过iOS一般用ppi,Android一般用dpi。
屏幕尺寸与分辨率
-
对角线长度(diagonal)
屏幕物理尺寸(英寸)。 -
分辨率(resolution)
屏幕上的像素总数,通常写作width*height
。
如分辨率1080*1920,表示设备水平方向上有1080个像素,垂直方向有1920个像素。
屏幕方向
手机(handset)与平板(tablet)通常有竖屏横屏两种使用的方向模式。
-
竖屏(portrait)
时宽度小于高度。 -
横屏(landscape)
时宽度大于高度。
一个分辨率1080*1920的设备。
处于竖屏模式时,屏幕宽高为 1080*1920。
处于横屏模式时,屏幕宽高为 1920*1080。
逻辑像素单位(dp/sp/pt)
开发时一般不直接使用物理像素(px)而是使用逻辑像素。
-
dp(dip, density-independent pixel)
密度无关像素,用于定义 Android 布局的位置和尺寸。在160dpi屏上1dp = 1px
。 -
sp(sip, scale-independent pixel)
缩放无关像素,用于定义文字大小,类似且默认等于 dp,使用此单位可让用户在运行时改变配置调整字体大小。 -
pt(point)
点,iOS 开发中用的逻辑像素单位,与 dp 基本上等价。 -
dp/in, pt/in
逻辑密度,每英寸逻辑像素数。
缩放系数/设备密度
-
缩放系数(scale)
逻辑像素渲染时的缩放比例因子,通过设备密度换算得到。 -
设备密度(device density)
Android厂商或ROM设置的虚拟屏幕密度,用户也能修改,用于计算缩放系数。
计算公式
-
高宽比($r$)
![](http://chart.googleapis.com/chart?cht=tx&chl=$r ={h \over w}$)
-
宽($w_{px}$), 高($w_{px}$), 高宽比($r$), 对角线($d_{in}$),密度($ppi_{px}$) 换算:
![](http://chart.googleapis.com/chart?cht=tx&chl=$ppi_{px}={d_{px} \over d_{in}}={\sqrt{{w_{px}2}+{h_{px}2}} \over d_{in}}= {w_{px} \cdot \sqrt{1+r^2} \over d_{in}}$)
以屏幕尺寸为4寸的iPhone 5为例,分辨率为1136x640,像素密度为326ppi。 而分辨率为1920x1080的家用21.5寸显示器,像素密度为103ppi。
-
根据设备密度($density$)计算缩放系数($scale$)
![](http://chart.googleapis.com/chart?cht=tx&chl=$scale = {density \over 160}$)
-
根据缩放系数($scale$),计算对应的逻辑单位(dp/pt)值
![](http://chart.googleapis.com/chart?cht=tx&chl=$w_{dp}={w_{px} \over scale}$)
![](http://chart.googleapis.com/chart?cht=tx&chl=$h_{dp}={h_{px} \over scale} $)
![](http://chart.googleapis.com/chart?cht=tx&chl=$ppi_{dp}={ppi_{px} \over scale}$)
var _ppi=function(w,r,d){return w*Math.sqrt(1+Math.pow(r,2))/d;};
var _w=function(r,d,ppi){return ppi*d/Math.sqrt(1+Math.pow(r,2));};
var _d=function(w,r,ppi){return w*Math.sqrt(1+Math.pow(r,2))/ppi;};
var _r=function(w,d,ppi){return Math.sqrt(Math.pow(d*ppi/w,2)-1);};
// wpx=1080, hpx=1920, d=5.5, scale=3
var _ws = function(wpx, hpx, d, scale) {
var r = hpx / wpx,
wpt=Math.round(wpx/scale),
hpt=Math.round(hpx/scale),
ppi=_ppi(wpx, r, d),
dppi=Math.round(ppi/scale);
return ['',Math.round(ppi),dppi,wpx+'x'+hpx,wpt+'x'+hpt,''].join('|');
}
_ws(1080, 1920, 5.5, 3);
设备数据
Android 屏幕密度分级
Android 将物理屏幕密度归纳成六个通用密度:
|屏幕密度|缩放系数|描述|
|---|---|:---|---|
|ldpi/120dpi|0.75|已绝迹,不用考虑
|mdpi/160dpi|1|320x480,市场份额不到1%
|hdpi/240dpi|1.5|480x800,480x854,540x960
3.5″左右各种的古董低端机
|xhdpi/320dpi|2|720x1280 4.7″~5.5″ 当前主流低端机,份额下滑中
|xxhdpi/480dpi|3|1080x1920 当前主流中高端机,一般5″以上
|xxxhdpi/640dpi|4|1440x2560 高端机型
|tvdpi/213dpi|1.33|用于电视设备
|nodpi|n/a|无视所有密度
设计时需要根据需求选择目标屏幕密度,建议使用xxhdpi(scale=3)。
自API19后增加的几个屏幕密度级别,设计时通常不需要考虑这些密度:
屏幕密度 | 缩放系数 | API | 代表机型 |
---|---|---|---|
280dpi | 1.75 | 22 | n/a |
360dpi | 2.25 | 23 | n/a |
400dpi | 2.5 | 19 |
Meizu MX3 5.1″ 1080x1800 Huawei Honor X2 7″ 1200x1920
|
420dpi | 2.625 | 23 | Google Nexus 5X 5.2″ 1080x1920 |
560dpi | 3.5 | 21 | Google Nexus 6P 5.7″ 1440x2560 |
Android 主流分辨率
取 baidu(2017-02)/qqmta(2017-04)/talkingdata(2017-04) 三家的分辨率统计数据
- 1080x1812,1080x1776... 合并到 1080x1920
- 720x1184,720x1196... 合并到 720x1280
- 480x800... 合并到 480x854
resolution | qqmta | baidu | talkingdata |
---|---|---|---|
1440x2560 | n/a | 2.83% | 2.15% |
1080x1920 | 46.77% | 37.90% | 44.81% |
720x1280 | 25.55% | 36.37% | 31.67% |
540x960 | 5.02% | 6.64% | 5.77% |
480x854 | 5.08% | 10.59% | 9.55% |
other | 19.6% | 5.67% | 6.05% |
设计通常应该基于逻辑分辨率作图,但仍然需要选一种像素分辨率作为基准
1080x1920 已经是占最大份额,且向上向下适配都能保持质量
所以设计作图以 1080x1920 为基准比较合适
Android 主流逻辑宽度
设备逻辑宽度(dp) = 设备宽度(px) / 缩放系数(scale)
逻辑宽度 | 份额 | 代表分辨率与设备 |
---|---|---|
360dp | 80+% | 1080x1920(主流增长中), 1440x2560(高端) 720x1280(主流下滑中), 540x960(淘汰中) |
320dp | 10+% | 淘汰中(480x854, 480x800) 已绝迹(320x480, 240x320) |
384dp | < 1% |
Meizu MX4 Pro 5.5″ 1536x2560 640dpi Meizu MX4 5.5″ 1152x1920 480dpi Meizu M1 5.0″ 768x1280 320dpi
|
400dp | < 1% | Meizu MX2 4.4″ 800x1280 320dpi |
432dp | < 1% | Meizu MX3 5.1″ 1080x1800 400dpi |
411dp | < 1% |
Le X820 5.7″ 1440x2560 560dpi Google Nexus 5X 5.2″ 1080x1920 420dpi
|
480dp | < 1% | Huawei Honor X2 7.0″ 1200x1920 400dpi |
360dp 目前占绝对主流(80+%),320dp 算少数派(约10%),基本上适配好这两个就能搞定大部分设备。
由于 Google 又搞出 560dpi,420dpi 等好几种密度,现在分辨率 1440x2560,1080x1920 中产生了 411dp 这种宽度,不知道以后还会有什么。
Android 设备屏幕数据
-
density
列是设备密度,用于计算缩放系数(scale)。 -
ppi
列是设备的物理密度。 -
scale
列表是缩放系数。 -
dp
列是设备逻辑分辨率。 -
ratio
列是屏幕比例。
参考:https://material.io/devices/
iOS 设备屏幕数据
|device|resolution|diagonal|ppi|scale|pt
|:---|---|---|---|---|---|---
|iPhone 2g/3g/3gs|320x480|3.5|163|@1x|320x480pt
|iPhone 4/4s|640x960|3.5|326|@2x|320x480pt
|iPhone 5/5s/5c/6se|640x1136|4|326|@2x|320x568pt
|iPhone 6/6s/7|750x1134|4.7|326|@2x|375x667pt
|iPhone 6+/6s+/7+|1242x2208|5.5|401|@3x|414x736pt
|iPad Mini|768x1024|7.9|162|@1x|768x1024pt
|iPad Mini Retina|1536x2048|7.9|324|@2x|768x1024pt
|iPad 1/2|768x1024|9.7|132|@1x|768x1024pt
|iPad 3/4/Air|1536x2048|9.7|264|@2x|768x1024pt
|iPad Pro|2048x2732|12.9|264|@2x|1024x1366pt
结合以上数据可知
- 屏幕密度有 @1x/@2x/@3x 三个级别
- iPad 只有一种逻辑宽度(768pt)
- iPhone 有3种逻辑宽度(414pt,375pt,320pt)
关于iPhone 6+/6s+/7+
- 它的缩放系数不再与物理密度相关,渲染缩放系数是3。
- 它的物理分辨率是 1080x1920,与渲染分辨率不一致,绘制时最终还是要进行缩放。
- 它的渲染分辨率是 1242x2208,对应的逻辑分辨率是(414x736pt),实际缩放系数(scale)是
1080/414=2.608
。 - 它还有个放大模式(1125x2001),对应的逻辑分辨率是(375x667pt),实际缩放系数(scale)是
1080/375=2.88
。
iOS 应用图标尺寸
device or context | scale | app | spotlight | settings | notification |
---|---|---|---|---|---|
iPhone 6+/6s+/7+ | 3x | 60pt | 40pt | 29pt | 20pt |
iPhone 6/6s/SE/7 | 2x | 60pt | 40pt | 29pt | 20pt |
iPad Pro | 2x | 83.5pt | 40pt | 29pt | 20pt |
iPad, iPad mini | 2x | 76pt | 40pt | 29pt | 20pt |
App Store | / | 1024px | / | / | / |
参考:iOS Human Interface Guidelines - App Icon
iOS 控件尺寸
控件 | 控件高度 | 控件内图标尺寸 |
---|---|---|
状态栏(Status bar) | 20pt | / |
标签栏(Tabbar) | 49pt | 约 25x25pt, 最大 48x32pt |
工具栏(Toolbar) | 44pt | 约 22x22pt |
导航栏(Navigation bar) | 44pt | 约 22x22pt |
支持多屏
目标
使得设备上某一元素在不同屏幕密度、分辨率、尺寸、方向上都具备合适的显示与交互效果。
宽度与高度
普通手机应用,大部分时候只需要竖屏显示,部分需要横屏显示。
这时只需要处理分辨率不同带来的问题。
优先适配宽度,少数场景需要要同时适配高度。布局与交互
当适配的尺寸跨度很大,比如平板,电视,横竖屏切换。
这时可能需要提供不同的布局甚至交互逻辑。
基于逻辑像素
由于各种屏幕的物理像素密度都有所不同,因此相同数量的物理像素在不同设备上的实际大小也有所差异,这样使用物理像素定义布局尺寸就会产生问题。
因此应当使用与密度无关的逻辑像素(dp/sp/pt)作为测量单位,这本质上是支持不同的屏幕密度。
控件自适应
就是适配屏幕的逻辑分辨率(主要是宽度),使控件在不同的逻辑分辨率上都有适当的显示效果。
方法就是尽量使用相对位置和尺寸,比如内边距(padding)/外边距(margin)/对齐(align)/百分比(percent)/权重(weight)/...
下图中几种常用的自适应方法从上到下依次是:
- 图片宽度根据容器自适应,高度等比缩放。
- 图片背景使用自动拉伸位图。
- 图片宽度固定,高度等比缩放,位置居中。
- 元素尺寸不变,间距自适应。
- 中间的元素占满剩余宽度。
- 文本流式。
响应式布局
当逻辑宽度不断变大到某个宽度,这时多出大量空间,原本的布局与交互流程已经不适应了。
这时就以这个宽度为断点提供一套新的布局与交互流程。
Google Material Design 以基于逻辑宽度(dp)的断点系统来适配不同尺寸的设备:
断点(dp) | 竖屏手机(handset)/平板(tablet) |
---|---|
360dp | small handset |
400dp | medium handset |
480dp | large handset |
600dp | small tablet |
720dp | large tablet |
840dp | large tablet |
960dp | n/a |
断点系统
https://material.io/guidelines/layout/responsive-ui.html#responsive-ui-breakpoints
适配流程
设定基准
以下为3种常用基准
- 360x640dp, 1080x1920, scale=3
- 360x640dp, 720x1280, scale=2
- 375x667pt, 750x1134, scale=2
根据实际需求选择合适的基准。
目前来说建议使用 360x640dp, 1080x1920, scale=3。
1080x1920 为目前份额最大的分辨率,向上放大到4x,向下缩小为2x都不会失去太多细节。
设计适配
常见设计工具
-
Photoshop
传统主流设计工具,辅以 cutterman/markman 等工具配合切图与标注。 -
Illustrator
矢量设计工具。 -
Sketch
矢量设计工具(Mac Only),功能强大,插件丰富(导出,标注,占位图,假数据)。 -
Xd(Experience Design)
Adobe 2016年推出与Sketch竞争的产品,简单轻量易上手,生态不足。
矢量图标库
建议
- 工具:优先使用矢量工具
Sketch
>Xd
>Illustrator
>Photoshop
。 - 设计:尽量使用相对位置和尺寸。
- 输出:切图以2x为主,失真过多的就输出3x甚至4x,应当输出一份矢量图标。
- 标注:使用逻辑度量单位(dp/pt),避免换算出小数。
参考
https://material.io/
https://material.io/devices/
https://developer.apple.com/ios/human-interface-guidelines
https://developer.android.com/training/multiscreen/screensizes.html