Skip to main content
版本:v2

屏幕适配

不同屏幕简介

可以在 设备基本信息 中查到各设备的屏幕形状和尺寸。

圆形屏幕的整个区域都供开发者绘制,而方形屏幕设备上则预先绘制了一个状态栏,以达到应用的统一性,如下图所示:

square screen

状态栏的高度为 64 px,左侧显示的是文本,右侧显示的是当前时间。文本默认为 app.json 中的 appName 字段,如果在 i18n 中配置了 appName 字段,则优先使用 i18n 中的配置。

有以下与状态栏相关的 API

适配方案

对开发者来说,希望是一份代码能够跑在各个设备上,在现阶段我们给出了这样的两条方案:

  • px 函数:对相同形状的屏幕使用 px 函数实现按屏幕进行比例大小缩放
  • 样式代码按形状区分组织:不同形状屏幕建议样式分屏幕形状分开组织,在运行时判断屏幕形状,读取相应的样式

px 全局函数

utils 模块实现了一个工具函数 utils - px

会以 小程序配置targets 对象中各机型配置的 designWidth 为基准进行等比例缩放。

举一个例子,某一应用 app.json 中的 targets 配置如下:

{
...
"targets": {
"gtr-3-pro": {
"designWidth": 480
},
"gtr-3": {
"designWidth": 480
},
}
}

在上文我们可以知道,GTR 3 PRO 机型的宽度为 480,GTR 3 机型的的宽度为 454

在下文中我们用 DEVICE_WIDTH 来指代设备的真实尺寸,那么 px(x) 函数运算的结果就是 Math.ceil(x / designWidth * DEVICE_WIDTH)

在 GTR 3 PRO 上,designWidth 的值在 app.json 中进行配置,为 480,查询本文档上方机型尺寸,找到 DEVICE_WIDTH 值为 480px(100) 的执行结果就是 Math.ceil(100 / 480 * 480) = 100

在 GTR 3 上,designWidth 的值在 app.json 中进行配置,为 480,查询本文档上方机型尺寸,找到 DEVICE_WIDTH 值为 454px(100) 的执行结果就是 Math.ceil(100 / 480 * 454) = 95

import { px } from '@zos/utils'

// 在 GTR 3 PRO 真机执行
console.log(px(100)) // 100

// 在 GTR 3 真机执行
console.log(px(100)) // 95

建议在进行 UI 设计时,圆屏统一以 480px 为基准,其余圆屏设备进行等比例缩放即可。

在编码层面,只需要在 app.json 中配置上缩放基准 designWidth 字段,在代码中适当的地方包裹 px 函数,就可以做到布局自适应。

import { createWidget, widget, text_style, align } from '@zos/ui'
import { px } from '@zos/utils'

const textStyle = {
x: px(96),
y: px(40),
w: px(288),
h: px(46),
color: 0xffffff,
text_size: px(36),
align_h: align.CENTER_H,
align_v: align.CENTER_V,
text_style: text_style.WRAP
}

const text = createWidget(widget.TEXT, textStyle)

样式代码按屏幕形状区分组织

与圆屏比起来,方屏在 UI 排版上发挥的空间更大一些,允许一款应用的 UI 在方屏和圆屏上会有部分不同,对于这种需求,给出一种代码组织思路:

核心思想是样式文件独立于逻辑存放,有单独的 styles.js,在运行时获取设备的形状和尺寸,根据不同的屏幕形状,导出不同的样式变量

通过 getDeviceInfo API 获取屏幕相关

index.style.js
import { getDeviceInfo, SCREEN_SHAPE_SQUARE, SCREEN_SHAPE_ROUND } from '@zos/device'
import { align, text_style } from '@zos/ui'
import { px } from '@zos/utils'

const deviceInfo = getDeviceInfo()
const { width, height, screenShape } = deviceInfo

const processStyles = (styleObj = {}) => {
return styleObj[screenShape]
}

const HOME_TITLE = {
[SCREEN_SHAPE_ROUND]: {
attrs: {
text: 'Hello World Round'
},
x: px(96),
y: px(40),
w: px(288),
h: px(46),
color: 0xffffff,
text_size: px(36),
align_h: align.CENTER_H,
align_v: align.CENTER_V,
text_style: text_style.WRAP
},
[SCREEN_SHAPE_SQUARE]: {
attrs: {
text: 'Hello World Square',
x: 32,
y: 11,
w: 232,
h: 42,
color: 0x666666,
text_size: 32,
align_h: align.CENTER_H,
align_v: align.CENTER_V,
text_style: text_style.NONE
}
}
}

export default {
HOME_TITLE: processStyles(HOME_TITLE)
}