HarmonyOS 7 新特性(三十八)|互动卡片:摇一摇、破框与状态机

HarmonyOS 7 的互动卡片让桌面内容从静态信息入口变成可触发、可动效、可与应用协作的轻量界面。摇一摇、前景元素出框、静态转动态等效果很吸引人,但卡片运行环境、内存预算、生命周期和事件能力都与普通页面不同。
高质量卡片不是把应用首页缩小,而是选择一个高频任务,用有限状态和明确事件在桌面完成。本文从卡片选型、状态机、事件路由、动效预算和降级验收展开。
一、先判断该做静态还是动态
静态卡片内存更小,适合信息展示、刷新和快捷跳转;动态卡片支持更丰富交互、动效和滑动。选型依据应是任务需求,不是视觉偏好。
interface WidgetRequirement {
needsAnimation: boolean
needsGesture: boolean
needsListInteraction: boolean
updateFrequencyPerHour: number
}
function chooseWidget(r: WidgetRequirement): 'STATIC' | 'DYNAMIC' {
return r.needsAnimation || r.needsGesture || r.needsListInteraction
? 'DYNAMIC' : 'STATIC'
}
只展示天气、票务状态或待办数量时,静态卡片通常更可靠。
二、卡片只承载一个核心任务
一张卡片最好回答一个问题或完成一个动作,例如“下一班车何时到”“今天还剩几个待办”“继续上次播放”。不要塞入完整导航、多个二级列表和复杂表单。
type WidgetModel = {
title: string
primaryValue: string
secondaryText?: string
primaryAction: 'OPEN' | 'REFRESH' | 'TOGGLE'
updatedAt: number
revision: number
}
模型字段受控,避免把整个业务对象序列化给卡片。
三、静态态与互动状态分离
卡片初始呈现应在不播放动效时也能表达信息。摇一摇等事件只是增强,不是唯一入口。
type CardState = 'STATIC' | 'ARMED' | 'ANIMATING' | 'RESULT' | 'COOLDOWN'
function transition(state: CardState, event: 'SHAKE' | 'END' | 'RESET'): CardState {
if (state === 'STATIC' && event === 'SHAKE') return 'ANIMATING'
if (state === 'ANIMATING' && event === 'END') return 'RESULT'
if (event === 'RESET') return 'STATIC'
return state
}
状态机应拒绝动画期间重复触发,避免堆积任务和状态错乱。

四、动效资源提前准备
卡片不是无限内存画布。图片、序列帧和粒子资源要压缩、分辨率匹配并控制数量。启动时临时解码大量资源会出现首帧空白。
interface MotionBudget {
maxDurationMs: number
maxLayers: number
maxBitmapBytes: number
maxConcurrentAnimations: number
}
const CARD_BUDGET: MotionBudget = {
maxDurationMs: 1200,
maxLayers: 6,
maxBitmapBytes: 2 * 1024 * 1024,
maxConcurrentAnimations: 2
}
具体限制以目标设备与官方规范为准,业务内部还应设置更保守的预算。
五、破框效果不能破坏可读性
前景元素出框可以制造空间感,但关键文本、操作按钮和状态不能跟随出框。需要定义安全区、裁剪区和触控区。
type SafeArea = { left: number; top: number; right: number; bottom: number }
function insideSafeArea(x: number, y: number, area: SafeArea) {
return x >= area.left && x <= area.right && y >= area.top && y <= area.bottom
}
在极窄、默认和极宽预览尺寸分别验证,避免只在设计稿尺寸正确。
六、事件通过稳定协议传递
动态 ArkTS 卡片可使用 postCardAction 与提供方应用协作,常见有 router、message 和 call。事件参数应版本化、白名单化。
postCardAction(this, {
action: 'router',
bundleName: 'com.example.app',
abilityName: 'EntryAbility',
params: {
route: '/task/today',
source: 'widget',
protocolVersion: 2
}
})
应用收到参数后再次校验,不能把任意字符串当成内部路由或命令执行。
七、更新使用 revision 防止倒退
卡片可能同时收到定时刷新、应用更新和云端推送。旧结果晚到时不能覆盖新状态。
function acceptUpdate(current: WidgetModel, incoming: WidgetModel): WidgetModel {
if (incoming.revision <= current.revision) return current
return incoming
}
时间戳不能完全替代版本号,因为设备时钟可能偏差。服务端或业务存储生成单调 revision 更稳妥。
八、离线和错误态必须独立设计
卡片刷新失败时保留最近成功内容,并标记更新时间;认证过期时展示“打开应用继续”,而不是空白。敏感信息在锁屏或账号退出时立即隐藏。
type WidgetViewState =
| { kind: 'READY'; model: WidgetModel }
| { kind: 'STALE'; model: WidgetModel; retryAfter: number }
| { kind: 'AUTH_REQUIRED' }
| { kind: 'EMPTY' }
错误提示应短而可行动,详细原因留在应用内。
九、减少动态与无障碍
用户开启减少动态时,摇一摇可直接切换结果或使用淡入,不播放位移和出框动画。卡片元素需要可理解名称、顺序和足够触控区域。
关键信息不能只靠颜色和运动表达。动画完成后读屏应获得新的状态,而不是重复朗读所有装饰元素。
十、测试不仅看预览器
官方工具支持多尺寸预览,但卡片不支持普通页面式调试,必须在真实桌面验证添加、删除、刷新、前后台、重启和系统资源回收。覆盖不同字体比例、语言、深浅色和弱网。
指标包括首次显示时间、更新成功率、内存、动画丢帧、重复事件、误触和从卡片到目标页的到达率。
十一、上线清单
- 静态/动态选型有明确任务依据;
- 卡片只承载一个核心任务;
- 无动效时仍能正确表达状态;
- 摇一摇和动画状态机防重复触发;
- 资源、层数和时长有预算;
- postCardAction 参数版本化并二次校验;
- 更新使用 revision 防止旧状态覆盖;
- 离线、过期、锁屏和减少动态均有降级;
- 多尺寸预览与真实桌面验收完成。

结语
互动卡片的创新不在于播放一次华丽动画,而在于用最小界面完成高频任务。把动态效果放在稳定静态态之上,用受控事件和单调版本连接应用,再用资源预算与无障碍降级守住边界,卡片才能既生动又可靠。
官方参考
- 创建服务卡片:https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/ide-service-widget
- 卡片事件能力说明:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-ui-widget-event-overview-V13
- HarmonyOS 7 新能力一览:https://developer.huawei.com/consumer/cn/features/
更多推荐



所有评论(0)