跳转至

UIKit 表盘开发

离线表盘

方案介绍

离线表盘总体方案:

  1. 将不同显示元素,拆分成不同的基础控件单元。
  2. 定义不同的数据类型,用于数据绑定及数据更新。
  3. 编写一个xml文件,里面写明控件类型(控件单元)、输入参数、周期配置、以及数据类型绑定。
  4. 提供一套python打包脚本,将xml中的信息、以及对应的资源打包成bin。
  5. native提供DialBinParser解析控件,用于解析bin。
  6. 提供DialViewGroup,用于管理控件的添加、周期管理、数据刷新,并继承cardpage,完成页面相关的管理机制。此控件即为最终的表盘页面。
  7. 提供一套model管理机制,用于更新数据。可参考“数据类型model”小节。

图 1 离线表盘整体方案

离线表盘整体方案

AOD离线表盘

状态机

在文件“display_state_machine.c”中定义了状态机的状态转移表g_state_change_matrix。g_state_change_matrix每个item分为:当前状态、输入掩码、输出状态、输出掩码。

图 1 display_state_machine.c

状态机displaystatemachine.c

图1所示,状态机的工作流程如下:

  1. “power_display_service.c”负责将各种表盘事件转换成输入掩码。
  2. “display_action.c”根据输入掩码和当前状态转换成输出状态和输出掩码,并将输出掩码转换成自定义函数。

可修改点:

  • 用户可以参考现存的状态转移表g_state_change_matrix自行修改进入和退出AOD表盘的输入掩码和输出掩码。
  • 可以修改“*_event_filter.c”,将不同的触发AOD(Always On Display,常亮显示)事件转换成输入掩码,例如将盖屏事件转换成“ENTER_AMBIENT”或“TURN_ON_SCREEN”。
  • 可修改“display_action.c”,将不同的输出掩码与进入AOD表盘函数对应起来,例如将“SET_DISPLAY_TO_IDLE_MODE”对应到切换AOD表盘,将“SET_DISPLAY_TO_NORMAL_MODE”对应到切换到主表盘。

注意,如需关闭AOD模式,请按照以下步骤修改文件内容:

  1. display_state_machine.c中屏蔽ambient相关代码。

    // 当前状态为Ambient
    // {
    //     SCREEN_AMBIENT,
    //     GET_ACTION_MASK(TURN_ON_SCREEN),
    //     SCREEN_ON,
    //     GET_ACTION_MASK(SET_DISPLAY_ON) |
    //     GET_ACTION_MASK(SET_TE_ON) |
    //     GET_ACTION_MASK(SET_DISPLAY_TO_NORMAL_MODE) |
    //     GET_ACTION_MASK(SET_TP_TO_NORMAL_WORK_MODE) |
    //     GET_ACTION_MASK(START_TIMER),
    // },
    // {
    //     SCREEN_AMBIENT,
    //     GET_ACTION_MASK(KEEP_CURRENT_STATE) |
    //     GET_ACTION_MASK(ENTER_AMBIENT) |
    //     GET_ACTION_MASK(RESET_TIMER),
    //     SCREEN_AMBIENT,
    //     GET_ACTION_MASK(SET_DISPLAY_ON) |
    //     GET_ACTION_MASK(SET_DISPLAY_TO_IDLE_MODE)
    // },
    // {
    //     SCREEN_AMBIENT,
    //     GET_ACTION_MASK(TURN_OFF_SCREEN),
    //     SCREEN_OFF,
    //     GET_ACTION_MASK(SET_DISPLAY_OFF) |
    //     GET_ACTION_MASK(SET_TE_OFF) |
    //     GET_ACTION_MASK(SET_TP_TO_SLEEP_MODE) |
    //     GET_ACTION_MASK(STOP_TIMER),
    // },
    
  2. display_action.c中屏蔽输出掩码操作。

    if ((action_bitmap & GET_ACTION_MASK(SET_DISPLAY_TO_IDLE_MODE)) != 0) {
        // notify_screen_aod_on_event();
    }
    if ((action_bitmap & GET_ACTION_MASK(SET_DISPLAY_TO_NORMAL_MODE)) != 0) {
        // notify_screen_aod_off_event();
    }
    

AodView

表 1 AodView成员函数

方法 描述
void AodView::OnStart() 初始化离线表盘和在线表盘。
void AodView::OnStop() 释放表盘资源操作,客户可以在此处释放在线表盘相关的资源。
UIViewGroup *AodView::InitAodDial(DialSetting &setting) 初始化在线表盘,客户可以在此函数进行扩展,返回自定义的在线表盘。
UIViewGroup *AodView::InitAodOffDial(DialSetting &setting) 初始化离线表盘。
UIViewGroup *AodView::InitDefaultAod() 初始化默认表盘,客户可以在此函数进行扩展,返回自定义的默认离线表盘。

当状态机进入Ambient状态,根据输出掩码,slice切换到AodView。AodView使用表1的成员函数初始化表盘,具体策略如下:

  1. 如果当前主表盘是离线表盘,进入AOD尝试初始化离线表盘,如果失败就初始化默认表盘。
  2. 如果当前主表盘是在线表盘,进入AOD尝试初始化在线表盘,如果失败就初始化默认表盘。

AOD离线表盘

AOD离线表盘方案特性:

  1. AOD离线表盘方案完全兼容离线表盘。
  2. 与普通离线表盘相比,除<dial>标签外,其余标签均新增“display_mode”属性,取值范围为"normal"、"ambient"、"always",分别表示该标签支持在正常模式下显示、AOD模式下显示、两种模式都显示。如果不显示指定该属性,则默认值是"normal"。

    须知: <dial>使用新的python工具时,“version”属性的值必须是3.0,否则会出现不可预知错误!

表盘制作

离线表盘制作相关的工具跟随版本发布包(3322_tools)发布。工具的目录地址:3322_tools/dial_converter_tool_OH。

工具执行脚本为:main.py。

脚本的执行方法可以参考示例文件:README.txt。

xml编写参考示例:instance/**/*.xml。

xml支持的标签和属性参考表1的说明。

须知: 表盘的工具version的值必须是“3.0”(脚本converter.py包含关键字“3.0”)!

表 1 xml 标签和属性说明

标签分类

标签

标签解释

属性:值类型

属性解释

取值范围

默认值

是否必须

备注

根节点

dial

根节点

指定表盘的基础信息

title:string

英文表盘名。

字符串

NA

must

-

zh_title:string

中文表盘名。

字符串

NA

option

-

description: string

表盘描述。

字符串

NA

must

-

size: int16_t int16_t

表盘大小。

(0,960]

NA

must

-

version: string

表盘协议号,格式:"x.x"。表盘工具制作的表盘支持的版本从"3.0"开始。

字符串

3.0

must

-

watch_version: string

表盘版本号,格式:"x.x.x",市场上表盘升级时使用。

字符串

1.0.0

must

-

preview_img: path

表盘预览图。

字符串

NA

must

-

tile_width: uint8_t

压缩宽度。

4、6、8、16

6

option

-

ambient_period:uint16_t

AOD模式下刷新周期,单位:ms。如果不设置,将会是60000,表示1分钟更新。

[16,60000]

60000

option

-

normal_peroid:uint16_t

正常模式下刷新周期,单位:ms。如果不设置,将会是60000,表示1分钟更新。

[16,60000]

60000

option

-

uuid: uint32_t

表盘唯一性标识。

32位十六进制正整数

NA

must

-

watch_type: uint8_t

表盘类型:智能手表(1)、运动手表(2)、运动手环(3)、儿童手表(4)。

[0, 255]

2

must

-

容器单元

options

容器控件,包含基本绘制单元:第一个数据为高级数据,第二个数据是备份数据,在高级数据不支持的情况下显示第二个备份数据

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

container

容器控件,包含基本绘制单元,至少包含一个控件,子控件位置为绝对位置

rect:int16_t int16_t int16_t int16_t

通过rect定义container的位置,格式:"left,top,width,height"。

(-32768,32767)

NA

must

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

基本绘制单元

label

文本

约束:只支持一行,不支持从右到左的文本

color: uint32_t (ARGB8888)

字体颜色。

32位十六进制正整数

0x00000000

must

-

font: string

系统的字库名;仅能指定一个,最大长度限制为64Byte。

字符串

NA

must

-

break_mode: adapt|stretch|wrap|ellipsis|marquee|clip

换行方式(只考虑单行的)。

adapt不支持文本对齐。

adapt|stretch|wrap|ellipsis|marquee|clip

ellipsis

must

-

rect: int16_t int16_t int16_t int16_t

文本显示区域。入参方式为:区域位置和区域宽高(x y w h)。

(-32768,32767)

(0 0 0 0)

must

-

text: string

文本,可以含有通配符,与绑定的数据相匹配。

字符串

NA

must

-

font_size: uint8_t

文本大小。

[0,255]

0

must

-

align: left|center|right

文本对齐方式。

left|center|right

left

must

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

bind_data: int16_t

绑定的数据类型,与通配符(%d、%s、%f)配合使用。

[0,32767)

0

option

-

is_periodic: true | false

是否需要周期刷新,AOD和正常模式下共用。

true|false

false

option

-

language: uint8_t

如果支持当前语言就显示该控件,默认255表示任何语言下都显示。支持的语言参考表3

[0, 255]

255

option

-

arc_label

弧形文本

center: int16_t int16_t

中心点。

(-32768, 32767)

(0,0)

must

-

radius: uint16_t

内半径。

[0, 32767)

0

must

-

start_angle: int16_t

起始角度。

[-360, 360)

0

must

-

end_angle: int16_t

结束角度。

(-360,360]

0

must

-

color: uint32_t (ARGB8888)

字体颜色。

32位十六进制正整数

0x00000000

must

-

font: string

系统的字库名;仅能指定一个,最大长度限制为64Byte。

字符串

NA

must

-

text: string

文本,可以含有通配符,与绑定的数据相匹配。

字符串

NA

must

-

font_size: uint8_t

文本大小。

[0,255]

0

must

-

align: left|center|right

文本对齐方式。

left|center|right

left

must

-

letter_space: uint8_t

文本字间距。

[0, 255)

0

option

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

bind_data: int16_t

绑定的数据类型,与通配符(%d、%s、%f)配合使用。

[0,32767)

0

option

-

is_periodic: true|false

是否需要周期刷新,AOD和正常模式下共用。

true|false

false

option

-

language: uint8_t

如果支持当前语言就显示该控件,默认255表示任何语言下都显示。支持的语言参考表3

[0, 255]

255

option

-

box_progress

条形进度条

rect: int16_t int16_t int16_t int16_t

进度条的显示范围。

(-32768,32767)

(0,0,0,0)

must

-

img_name: path

进度条的前景图片(img_name|color|(gradient_colors & gradient_stops)三选一)。

字符串

NA

option

-

color: uint32_t (ARGB8888)

进度条的颜色(img_name|color|(gradient_colors & gradient_stops)三选一)。

32位十六进制正整数

NA

option

-

gradient_colors: uint32_t uint32_t ...

线性渐变的过渡颜色,与gradient_stops匹配使用(img_name|color|(gradient_colors & gradient_stops)三选一)。

32位十六进制正整数

NA

option

-

gradient_stops: float float ...

线性渐变的过渡点,与gradient_colors匹配使用。

0~1

NA

option

-

cap_type: none | round

cap样式。

none | round

none

must

-

direction: left_to_right | right_to_left | top_to_bottom | bottom_to_top

方向。

left_to_right | right_to_left | top_to_bottom | bottom_to_top

left_to_right

must

-

background_color: uint32_t

背景色。

32位十六进制正整数

0x00000000

option

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

bind_data: int16_t

绑定的数据类型。

[0,32767)

0

must

-

is_periodic: true|false

是否需要周期刷新,AOD和正常模式下共用。

true|false

false

option

-

arc_progress

弧形进度条

rect: int16_t int16_t int16_t int16_t

进度条的显示范围。

(-32768,32767)

(0,0,0,0)

must

-

img_name: path

进度条的前景图片(img_name|color|(gradient_colors & gradient_stops)三选一)。

字符串

NA

option

-

color: uint32_t (ARGB8888)

进度条的颜色(img_name|color|(gradient_colors & gradient_stops)三选一)。

32位十六进制正整数

NA

option

-

gradient_colors: uint32_t uint32_t ...

线性渐变的过渡颜色,与gradient_stops匹配使用(img_name|color|(gradient_colors & gradient_stops)三选一)。

32位十六进制正整数

NA

option

-

gradient_stops: float float ...

线性渐变的过渡点,与gradient_colors匹配使用。

0~1

NA

option

-

cap_type: none | round

cap样式。

none | round

none

must

-

radius: uint16_t

内半径。

[0, 32767)

0

must

-

start_angle: int16_t

起始角度。

[-360, 360)

0

must

-

end_angle: int16_t

结束角度。

(-360, 360]

0

must

-

background_color: uint32_t

背景色。

32位十六进制正整数

0x00000000

option

-

line_width: int16_t

线宽。

[0, 32767)

0

must

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

bind_data: int16_t

绑定的数据类型。

[0,32767)

0

must

-

is_periodic: true|false

是否需要周期刷新,AOD和正常模式下共用。

true|false

false

option

-

static_img

静态图片,不与数据绑定。可以用作背景。使用AutoEnable模式,支持点击交互和时间触发交互

position: int16_t int16_t

控件绝对位置,控件的宽高(x,y)与图片一致。

(-32768,32767)

(0,0)

must

-

center: int16_t int16_t

旋转中心点。

(-32768,32767)

(0,0)

option

-

rotate: float

图片旋转角度。

[0, 360]

0

option

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

img_names: path,path...

图片路径。说明:

  1. 多张图可以支持点击交互,点击控件会自动切换到下一张图片。
  2. 单张图无交互。
  3. 最多支持3张图片切换。

字符串

NA

must

-

language: uint8_t

如果支持当前语言就显示该控件,默认255表示任何语言下都显示。支持的语言参考表3

[0, 255]

255

option

-

time_intervals: string

时间段的设置,格式:a-b c-d。

说明:用于在设置的时间段内显示,支持多区间设置,多区间之间不重叠。时间设置单位小时,24小时制,左闭右开。

例如:设置“9-12 14-18”,表示9:00到11:59:59和14:00到17:59:59这段时间显示该控件,非这段时间不显示该控件。

字符串

0-24

option

-

sequence_img

序列帧,不与数据绑定。支持交互,拥有子节点imgs(最多支持3个,最少1个),并且只有第一个子节点可以设置成循环播放,其他字节只能设置非循环播放

position: int16_t int16_t

控件绝对位置,控件的宽高(x,y)与图片一致。

(-32768,32767)

(0,0)

must

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

interval: uint16_t

序列帧切换间隔。单位:ms。

(0, 32767)

0

must

imgs

一套序列帧图片资源

names: path,path...

指定序列帧的所有图片名,中间通过逗号隔开。

字符串

NA

must

-

repeat: true | false

是否循环播放。

true|false

false

must

-

rotate_img

可动态旋转的图片,与数据绑定。通过绑定不同的数据,可以实现时间指针自动旋转、图片自动旋转。使用AutoEnable模式

img_name: path

指定可旋转图片的文件名。

字符串

NA

must

-

position: int16_t int16_t

控件绝对位置,控件的宽高(x,y)与图片一致

(-32768,32767)

(0,0)

must

-

rotate_center: float float

旋转中心点。

浮点数

0.0

must

-

rotate_start: int16_t

旋转起始角度。

[-360, 360)

0

must

-

rotate_end: int16_t

旋转结束角度。

(-360, 360]

0

must

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

bind_data: int16_t

绑定旋转的数据,数据值为比例值。

[0,32767)

0

must

-

is_periodic: true|false

是否需要周期刷新,AOD和正常模式下共用。

true|false

false

option

-

option_img

可动态变化的图片,与数据绑定。使用AutoEnable模式,支持时间触发交互

img_names: path,path...

动态选择的所有图片名,中间通过逗号隔开。

字符串

NA

must

-

position: int16_t int16_t

控件绝对位置,控件的宽高(x,y)与图片一致。

(-32768,32767)

(0,0)

must

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示

normal|ambient|always

normal

option

-

bind_data: int16_t

绑定的数据类型,数据类型为整数。

[0,32767)

0

must

-

is_periodic: true|false

是否需要周期刷新,AOD和正常模式下共用。

true|false

false

option

-

language: uint8_t

如果支持当前语言就显示该控件,默认255表示任何语言下都显示。支持的语言,参考表3

[0, 255]

255

option

-

time_intervals: string

时间段的设置,格式:a-b c-d

说明:用于在设置的时间段内显示,支持多区间设置,多区间之间不重叠。时间设置单位小时,24小时制,左闭右开。

例如:设置“9-12 14-18”,表示9:00到11:59:59和14:00到17:59:59这段时间显示该控件,非这段时间不显示该控件。

字符串

0-24

option

-

digital_img

可表达数字的图片组合,与数据(数字)绑定。使用AutoEnable模式,支持时间触发交互

img_names: path,path...

数字图片, 0~9。

字符串

NA

must

-

sign_img_name: path

符号位。

字符串

NA

option

-

space: uint16_t

图片间隔。

[0, 32767)

0

must

-

align: left|center|right

图片对齐方式。

left|center|right

left

must

-

align_pos: uint16_t uint16_t

图片对齐坐标点。

[0, 32767)

(0,0)

must

-

integer_length: uint8_t

指定整数长度。

0,使用实际长度。

>0,限定长度,实际长度不足,则前方补零,超过则报错。

0

option

-

img_decimal_point: path

如果配置该变量,意味着显示的为浮点数。

字符串

NA

option

-

decimal_precision: uint8_t

小数精度,必须配置img_decimal_point才生效。

[0, 255]

0

option

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

bind_data: int16_t

绑定的数据类型。

[0,32767)

0

must

-

is_periodic: true|false

是否需要周期刷新,AOD和正常模式下共用。

true|false

false

option

-

time_intervals: string

时间段的设置,格式:a-b c-d

说明:用于在设置的时间段内显示,支持多区间设置,多区间之间不重叠。时间设置单位小时,24小时制,左闭右开。

例如:设置“9-12 14-18”,表示9:00到11:59:59和14:00到17:59:59这段时间显示该控件,非这段时间不显示该控件。

字符串

0-24

option

-

video

视频

rect: int16_t int16_t int16_t int16_t

视频控件的显示范围。

与视频帧宽高保持一致。

(-32768,32767)

(0,0,0,0)

must

-

source: string

指定视频的路径。

字符串

NA

must

-

color_key: uint32_t

ARGB8888,指定ColorKey的颜色。

32位十六进制正整数

0xfffbfbfb

must

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

preview_frame: string

指定视频预览帧的路径。

字符串

NA

must

-

click

点击跳转配置

rect: int16_t int16_t int16_t int16_t

可点击区域。

(-32768,32767)

(0,0,0,0)

must

-

action_slice: uint32_t

跳转到 slice,与 action_bundle 二选一(在 [AppViewIDs.h](https://gitcode.com/HiSpark/hs-fbb/blob/master/src/application/wearable/nativeapp/nativelauncher/include/AppViewIDs.h) 中查看 AppViewId)。

参考<跳转应用定义>

NA

option

-

action_bundle: bundle_name

跳转到JS页,与action_slice二选一。

字符串(bundle_name是JS的bundleName)

NA

option

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

kaleidoscope

万花筒

img_name: path

万花筒图片。

字符串

NA

must

-

crown_rotate_step: float

表冠旋转步进值。

浮点型

1.0

option

-

animator_rotate_step: float

动画播放旋转步进值。

浮点型

0.0

option

-

display_mode: normal|ambient|always

"normal":只在正常亮屏模式下导入该控件。如果该属性没有,默认是normal下显示。

"ambient":该控件只在AOD模式下显示。

"always":两种模式下都显示。

normal|ambient|always

normal

option

-

说明:

  • 默认值生效场景:must属性传输错误时;option属性未设置时。
  • 各标签的bind_data属性赋值,参照“/src/application/wearable/nativeapp/nativeui/include/main/dial/DialDataType.h”文件中的枚举值。值的范围匹配不同的数据类型,具体参照表2
  • 当前所有设置图片资源的属性,请使用标准png或者jpg格式图片。支持图片格式:RGB565、RGB888、ARGB8888。
  • 若标签为周期性的,需要绑定data type;非周期性标签可以不绑定。

表 2 bind_data范围定义

取值范围

是否自定义

匹配数据类型

对应接口

[0,4095]

单浮点类型

void HandleFloatData(float data)

[4096,8191]

[8192,12287]

文本类型

void HandleTextData(const std::string* data, uint16_t num)

[12288,16383]

[16384,20479]

多浮点类型

void HandleFloatData(const float* data, uint16_t num)

[20480,24575]

表 3 语言

语言代码

id

zh

0

en

1

all(所有语言)

255

须知: binddata跟随oh官网定义: https://gitee.com/cooperation-team-L0UI/watch_face/blob/master/face_tool/%E8%A1%A8%E7%9B%98%E5%B7%A5%E5%85%B7%E6%A0%87%E5%87%86/xml%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B.xlsx

数据类型model

离线表盘数据由model提供,分为主动获取与被动通知两种方式。当标签设置为周期类,绑定一个data后,周期主动获取数据;非周期类,绑定了data的,则注册回调,被动更新数据。

model采用factory模式管理,方便扩展以及对上层解耦。当前支持了一部分数据类型,客户可以根据自身情况进行类型扩展。

model设计如图1所示。

图 1 model设计

model设计

ModelDialDataFactory 向上提供查询及注册接口;DialBaseModel 为基类;DialModelxxx 继承 DialBaseModel,并通过 REGIST_DIAL_MODULE 静态往 factory 中注册,factory 中管理 model 链表。详细信息,可参考 ModelListenerSample.cpp 代码实现。

当前数据类型分float、text、multi float三类,分别对应三个分段DATA_TYPE_FLOAT_BASE、DATA_TYPE_TEXT_BASE、DATA_TYPE_MULTI_FLOAT_BASE。如需扩展,请按数据类型新增对应的枚举值。每个枚举值只能对应一个model,而一个model可能对应多个枚举类型,比如DialModelTime。

扩展新的model类型,需新增datatype,继承DialBaseModel并重写需要的数据接口,然后通过REGIST_DIAL_MODULE进行注册即可。详细可参考现有的dial model。

相关类介绍

DialViewGroup

DialViewGroup继承于CardPage,可直接作为crossview的一个页面使用;同时,它也继承于OnDialDataUpdateListener,用于model数据更新时用于通知上层的回调。主要函数如表1所示。

表 1 DialViewGroup主要函数

函数

介绍

void SetDial(std::string filePath, DisplayState state = DisplayState::NORMAL)

设置表盘资源路径。

uint8_t GetPeriod(void)

获取表盘刷新周期。

void UpdateViewsByPeriodicUpdateData()

通知表盘更新数据(周期性主动获取数据)。

DialBaseModel

DialBaseModel为model基类,所有的model均继承于此类,主要函数如表1所示。

表 1 DialBaseModel主要函数

函数

介绍

void RegisterDialDataListener(OnDialDataUpdateListener* listener)

注册回调函数,用于被动数据上报方式。当model数据变化时,会调用注册进来的listener。

bool UnRegisterDialDataListener()

注销回调函数。

bool GetDialTextData(DialDataType& type, std::string*& out, int16_t& strNum)

获取字符串数据。

  • type:数据类型。
  • out:数据指针,用于带回字符串内容。
  • strNum:带回的字符串个数。

bool GetDialFloatData(DialDataType& type, float& out)

获取单个float数据。

  • type:数据类型。
  • out:带回float数据的变量。

bool GetDialFloatData(DialDataType& type, float*& out, int16_t len)

获取多个float数据。

  • type:数据类型。
  • out:数据指针,用于带回float数据buffer。
  • len:带回的float数据个数。

ModelDialDataFactory

ModelDialDataFactory用于管理model链表,并对上提供数据查询及回调注册接口,主要函数如表1所示。

表 1 ModelDialDataFactory主要函数

函数

介绍

bool RegisterDialDataListener(DialDataType type, OnDialDataUpdateListener* listener)

注册回调函数:通过type查询到具体的model,并调用model相应的接口。

bool UnRegisterDialDataListener(DialDataType type)

注销回调函数:通过type查询到具体的model,并调用model相应的接口。

bool GetDialTextData(DialDataType& type, std::string*& out, int16_t& strNum)

获取字符串数据:通过type查询到具体的model,并调用model相应的接口。

bool GetDialFloatData(DialDataType& type, float& out)

获取单个float数据:通过type查询到具体的model,并调用model相应的接口。

bool GetDialFloatData(DialDataType& type, float*& out, int16_t& len)

获取多个float数据:通过type查询到具体的model,并调用model相应的接口。

协议说明

图 1 Bin文件的数据说明

Bin文件的数据说明

说明:

  • Dial[Type] 支持类:DialStaticImg、DialSequenceImg、DialRotateImg、DialOptionImg、DialDigitalImg、DialLabel、DialArcLabel、DialProgressType、DialBoxProgress、DialArcProgress、DialVideo、DialClick、DialKaleidoscope。
  • 具体 DialHeader 和 DialVIew 结构体成员顺序请参考 DialBinTypes.h 文件。
  • DialHeader和DialVIew结构体成员说明请参考“表盘制作”章节的标签控件。

在线表盘

简介

表盘是手表最为基础的界面,其基本功能是为用户提供时间信息,但随着智能手表的发展,表盘上嵌入了越来越多的元素,比如电量信息、步数、心跳等,方便用户快速获取更多关键信息,如图1所示。为了适应不同客户的定制需求,我们支持在线表盘和离线表盘两种类型:

  • 离线表盘:通过加载和解析本地文件存储的表盘描述信息来生成表盘,用户只需要根据约定好的规则去制作表盘描述文件即可,不需要太关心代码实现,开发门槛低,但这也一定程度降低了灵活性。
  • 在线表盘:通过直接编程来生成表盘,所有表盘的元素都直接通过代码描述,用户需要深度理解代码,掌握图形界面开发技能,开发门槛较高,但同时开发者可以更灵活的实现想要的效果。

本章主要介绍在线表盘的开发指导。

图 1 在线表盘样例

在线表盘样例

参考实现

新增一个在线表盘,用户至少需要实现两个文件:

  1. 表盘头文件,参考:/src/application/wearable/nativeapp/nativeui/include/clock/MainClockView.h
  2. 表盘源文件,参考:/src/application/wearable/nativeapp/nativeui/clock/src/MainClockView.cpp

表盘实现关键要点如下:

  • 新增的表盘类应继承UICardPage,UICardPage是UIViewGroup的子类,提供容器功能,同时UICardPage被设计用于和UICrossView配合,比如在表盘支持上下滑动、左右滑动进入其它页面。
  • 新增表盘需要实现构造函数,并在其中设置界面的位置起点、宽高。
  • 新增表盘需要重载PreLoad接口,并在其中完成各种表盘元素的创建和初始化,并调用SetCoverable(true),以支持其它应用界面遮盖表盘界面。
  • 在PreLoad接口中,如果是定制模拟表盘场景,可创建UISweepClock实例,其提供了扫描时钟相关的基本能力,同时它最终继承自UIViewGroup,提供了容器功能,表盘上的所有UI元素都应该被添加到这个容器中,然后UISweepClock实例应该被添加到新增的表盘类。
  • 注意:因为主表盘是常用界面,为了提升回到主表盘流畅度,请不要在UnLoad接口中销毁释放表盘资源,相关操作应该放在表盘的析构函数中。
  • 除此之外,用户还需要修改“/src/application/wearable/nativeapp/nativelauncher/include/UiConfig.h”,在DialId中增加新增表盘的枚举。

注册方案

为了将用户定制表盘的实例化与框架解耦,支持在线表盘静态注册方案,用户注册后,框架会根据运行模式和表盘类型,自适应创建对应表盘的实例。用户需要在新增的表盘源文件中,使用注册宏完成注册,调用形式为:REGIST_WATCH_DIAL(mode, id, U),其中参数解释如下:

  • mode:显示模式,定义在“UiConfig.h”中的DialDisplayMode中,公板支持主表盘(DIAL_DISPLAY_MODE_MAIN)和AOD表盘(DIAL_DISPLAY_MODE_AOD),用户根据实际情况选择入参。
  • id:表盘ID,定义在“UiConfig.h”的DialId中,需要将用户自定义的表盘id作为入参。
  • U:表盘类模板,需要将自定义的表盘类作为入参。

注册一个main模式下的表盘,参考样例如下:REGIST_WATCH_DIAL(DIAL_DISPLAY_MODE_MAIN, DIAL_CLOCK, MainClockView);

桌面样式

简介

桌面样式指的是应用图标在桌面上的组织和呈现方式,最典型的桌面样式为列表风格(如图1),通过上下滑动翻页,寻找想要的应用,再点击启动应用。当前提供列表、足球、蜂窝和瀑布等桌面样式。

图 1 列表风格桌面

列表风格桌面

参考实现

新增一个桌面样式,用户至少需要实现两个文件:

桌面样式实现关键要点:

  1. 新增的桌面样式类应继承并实现UIDesktopFragment接口(其定义如图1),UIDesktopFragment通过继承多个父类,拥有自己的生命周期,支持处理点击、滚动和旋转事件,内部持有UIViewGroup实例,可提供容器功能;以上关键类的关系如图2所示。

    图 1 UIDesktopFragment定义

    UIDesktopFragment定义

    图 2 UIDesktopFragment类图

    UIDesktopFragment类图

    UIDesktopFragment关键接口说明如表1所示。

    表 1 UIDesktopFragment关键接口说明

    接口

    接口描述

    AddAppItemToList

    将应用添加到桌面,并生成对应风格的图标,是一个纯虚函数,客户定制桌面必须实现此接口。

    ClearAppItemToList

    清空桌面,并销毁桌面图标相关的资源,是一个纯虚函数,客户定制桌面必须实现此接口。

    RefreshAppList

    刷新桌面图标布局,在更新桌面应用后被调用,是一个纯虚函数,客户定制桌面必须实现此接口。

    OnCreateView

    在创建桌面时被调用,开发者应该在此接口中创建、初始化对应风格的容器,并调用fragmentView_.Add(xxx)将容器添加到UIFragment持有的容器中(UIFragment持有的容器已被添加到RootContainer);客户定制桌面必须重载此接口。

    OnDestroyView

    在销毁桌面时被调用,开发者应该在这个接口中销毁所有资源,客户定制桌面必须重载此接口。

    OnResumeView

    这个接口没有在UIDesktopFragment中显示声明,它是继承自UIFragment的接口,用于处理桌面显示前的定制动作,客户可按需实现。

    SwitchView

    用户点击桌面图标时,切换到对应的应用界面,客户定制桌面的OnClick回调中,建议统一调用此接口。

    OnClick

    响应用户点击事件,进入到对应的应用界面,内部调用SwitchView接口完成切换即可,客户定制桌面必须重载此接口;参考表1。

    OnRotate

    响应用户旋转桌面的事件,重新绘制桌面,客户可按需实现;参考表5。

  2. 新增桌面样式应继承UIImageView并实现对应风格的xxxItemView类,用于管理桌面团标,可以将相关代码和主类放在一个文件中;这部分实现较为简单,不做赘述,客户可参考上述xxxDesktopFragment.cpp(.h)中的FootballItemView、HexagonsItemView、WaterfallItemView等实现。

新增实现以上类之外,用户还需要以下操作:

  1. 修改“/src/application/wearable/nativeapp/nativeui/include/settings/model/SettingDesktopModel.h”,在DesktopStyle中增加新增桌面的枚举类型。
  2. 在setting模块中,增加对应桌面选择样式的入口。

注册方案

为了将客户定制桌面样式的实例化与框架解耦,支持桌面样式静态注册方案,用户注册后,框架会根据设置的风格自适应创建对应桌面的实例。用户需要在新增的桌面样式源文件中,使用注册宏完成注册,调用形式为:REGIST_DESKTOP_STYLE(style, D),其中参数解释如下:

  • style:桌面样式风格,定义在“SettingDesktopModel.h”的DesktopStyle中,需要将用户自定义的桌面style作为入参。
  • D:桌面风格类模板,需要将自定义的桌面类作为入参。

注册一个新的桌面样式,参考样例如下:REGIST_DESKTOP_STYLE(APPLIST_STYLE, ListDesktopFragment);