移动应用多屏支持

基础概念

常见尺寸单位

  • 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$)

    $r ={h \over w}$

  • 宽($w_{px}$), 高($w_{px}$), 高宽比($r$), 对角线($d_{in}$),密度($ppi_{px}$) 换算:

    $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$)

    $scale = {density \over 160}$

  • 根据缩放系数($scale$),计算对应的逻辑单位(dp/pt)值

    $w_{dp}={w_{px} \over scale}$

    $h_{dp}={h_{px} \over scale}$

    $ppi_{dp}={ppi_{px} \over scale}$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 列是屏幕比例。

android phones

参考: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竞争的产品,简单轻量易上手,生态不足。

矢量图标库

建议

  1. 工具:优先使用矢量工具 Sketch > Xd > Illustrator > Photoshop
  2. 设计:尽量使用相对位置和尺寸
  3. 输出:切图以2x为主,失真过多的就输出3x甚至4x,应当输出一份矢量图标
  4. 标注:使用逻辑度量单位(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

欢迎打赏,谢谢支持~