本文基于 HarmonyOS 7(API 26)官方《互动卡片开发实践》、Form Kit 场景动效卡片开发指导与新能力一览整理。文中代码是为说明链路自写的示意示例,不是官方示例的搬运,接口签名以官方 SDK 为准;涉及真机表现与机型支持的部分均已明确标注,未做任何实测数据编造。

引子:桌面上的卡片,终于不只是"一张图"
V哥先说一个大家都有体感的场景。外卖应用的桌面卡片,显示"骑手距您 800 米"------信息是对的,但它是死的。用户想看骑手走到哪了,只能点开应用;卡片永远是那几张数据刷新出来的静态截图,无论你把 UI 做得多精致,它的本质都是"一张会换内容的图"。
HarmonyOS 7(API 26)把这件事改了。官方新能力一览里的原话是(HarmonyOS 7 新能力一览):
互动卡片新增通过摇一摇手机,触发卡片静态转动态、前景元素出框等效果,表现更生动,帮助提升应用曝光与交互转化。
V哥读这段话抓三个关键词:摇一摇触发 ------不用点、不用进应用,物理动作直达卡片;静态转动态 ------卡片有了激活态,能跑真正的动画;出框------动效渲染区域可以突破卡片自身边界。曝光与转化提升是官方的定性表述,具体幅度官方没给数据,实际收益以你自己的运营数据为准。
这期V哥把互动卡片这条链路完整拆开:它到底是什么、摇一摇从传感器到动画页经过哪几站、代码怎么写,最后给一份V哥自己的判断------哪些业务值得做互动卡片,哪些是在浪费配额。
一、先分清:你要接的是"场景动效卡片"
互动卡片在 HarmonyOS 7 里分两种类型:趣味交互类型 (funInteractionParams)和场景动效类型 (sceneAnimationParams)。摇一摇触发属于后者------官方最佳实践明确写的是"本文仅介绍场景动效类型互动卡片"(互动卡片开发实践)。
两者的共同骨架是:卡片有一个普通态 和一个激活态 。普通态就是你现在熟悉的动态卡片,由 FormExtensionAbility 管理;激活态则是系统创建一个 LiveFormExtensionAbility 实例,拉起一个完整的 ArkTS 页面来承载动画和交互。官方示例场景很能说明它适合干什么:睡眠卡片起床时气球飘出卡片边界、快递卡片包裹运输动画、音乐卡片切歌时角色出框取专辑。
这里V哥要先纠正一个最容易走偏的理解------动态化不靠视频,也不靠 GIF/帧动画资源包 。官方给出的技术路径是:激活态加载的是一个真正的 ArkTS UI 页面,动画用 ArkUI 的动效能力实现,LiveFormInfo 会把卡片尺寸、圆角等信息传进去,你的动画是矢量驱动、随卡片规格自适应的。理解了这一点,很多问题就有答案了:为什么出框范围有限制(系统按卡片规格裁剪渲染区域)、为什么动画页要同步加载(它是独立 ExtensionAbility 的生命周期)。
还有一个硬边界先说在前:摇一摇激活互动卡片能力仅在 HarmonyOS 7.0 及以上版本触发,开发环境要求 DevEco Studio 6.1.0 Release 及以上。老系统上的降级表现,以官方文档为准------发布策略要按这个前提设计。
二、摇一摇的完整链路:从甩手机到动画页,一共七站
V哥把官方最佳实践里的摇一摇触发流程画成一张图:

官方的七步流程,V哥用大白话复述一遍:
- 用户摇动设备 ,系统识别摇一摇事件------注意,摇动事件的识别是系统级的,你不需要自己订阅加速度传感器;
- 系统查找
sceneAnimationParams.triggerTypes里配了"shake"的卡片; - 系统读取
sceneAnimationParams.abilityName,找到对应的LiveFormExtensionAbility; - 系统把事件送达
FormExtensionAbility的onUpdateForm; - 开发者在其中调用
requestOverflow请求激活互动卡片; - 系统自动创建
LiveFormExtensionAbility实例; - 调用
onLiveFormCreate,加载动画 UI。
这七步里开发者真正要写代码的只有两处:配置 (第 2、3 步的声明)和激活 + 动画页(第 5、7 步)。传感器监听、实例创建、生命周期管理全是系统的活。这是V哥认为这套设计最聪明的地方------把"设备运动"这种最容易做脏的输入(功耗、误触、后台保活)收归系统,开发者只声明意图。
三、动手:三段代码接完整条链路
以下代码是V哥按官方文档写的示意示例,接口签名与常量以官方 SDK 为准。
第一段:声明卡片与 LiveFormExtensionAbility
在 form_config.json 里给卡片加 sceneAnimationParams 标签:
json5
{
"forms": [
{
"name": "DeliveryCard",
"src": "./ets/widget/pages/DeliveryCard.ets",
"uiSyntax": "arkts",
"defaultDimension": "2*2",
"supportDimensions": ["2*2"],
"sceneAnimationParams": {
"abilityName": "DeliveryLiveCardAbility", // 触发后要激活的互动卡片
"triggerTypes": ["shake"] // 摇一摇触发,API 26 起支持
}
}
]
}
再在 module.json5 里声明这个 ExtensionAbility,type 必须是 liveForm:
json5
{
"extensionAbilities": [
{
"name": "DeliveryLiveCardAbility",
"srcEntry": "./ets/livecardability/DeliveryLiveCardAbility.ets",
"type": "liveForm", // 固定值:声明为互动卡片类型
"exported": false
}
]
}
第二段:摇一摇到达,requestOverflow 激活
摇一摇事件会打进 FormExtensionAbility 的 onUpdateForm,V哥在这里请求激活(示意):
typescript
// EntryFormAbility.ets ------ 收到系统摇一摇事件,请求激活互动卡片
import { formProvider, formInfo } from '@kit.FormKit';
// 溢出比例与时长有系统上限约束,具体取值以官方文档为准
const LIVE_CARD_RATIO: number = 0.25;
const LIVE_CARD_DURATION: number = 3000;
export default class EntryFormAbility extends FormExtensionAbility {
async onUpdateForm(formId: string): Promise<void> {
// ① 先查卡片真实尺寸,出框区域要按它计算
const rect: formInfo.Rect = await formProvider.getFormRect(formId);
// ② 居中扩展出框区域:left/top 为负值,向四周扩展
const area: formInfo.OverflowInfo = {
area: {
left: -(rect.width * LIVE_CARD_RATIO / 2),
top: -(rect.height * LIVE_CARD_RATIO / 2),
width: rect.width * (1 + LIVE_CARD_RATIO),
height: rect.height * (1 + LIVE_CARD_RATIO)
},
duration: LIVE_CARD_DURATION
};
// ③ 请求激活:系统据此创建 LiveFormExtensionAbility
await formProvider.requestOverflow(formId, area);
}
}
除了摇一摇路径,官方示例里四张卡片还都支持点击触发 :卡片内通过 postCardAction({ action: 'message' }) 发消息,onFormEvent 里收到 requestOverflow 消息后同样调 formProvider.requestOverflow。配套的还有 formProvider.cancelOverflow(取消激活)------激活态 UI 被点击时用它收尾。
第三段:onLiveFormCreate,同步加载动画页
typescript
// DeliveryLiveCardAbility.ets ------ 互动卡片激活态的管理者
import { LiveFormInfo, LiveFormExtensionAbility } from '@kit.FormKit';
import { UIExtensionContentSession } from '@kit.AbilityKit';
export default class DeliveryLiveCardAbility extends LiveFormExtensionAbility {
onLiveFormCreate(liveFormInfo: LiveFormInfo, session: UIExtensionContentSession): void {
let storage: LocalStorage = new LocalStorage();
// 卡片尺寸、圆角传给动画页,动画要贴着真实卡片边界做
storage.setOrCreate('formId', liveFormInfo.formId);
storage.setOrCreate('borderRadius', liveFormInfo.borderRadius);
storage.setOrCreate('formRect', liveFormInfo.rect);
// V哥提醒:loadContent 必须同步调用,网络/数据库等异步加载放到它之后,
// 否则激活瞬间动画页白屏------这是官方最佳实践专门点名的问题
try {
session.loadContent('livecardability/pages/DeliveryLiveCard', storage);
} catch (e) {
console.error('loadContent error');
}
}
onLiveFormDestroy(liveFormInfo: LiveFormInfo): void {
// 释放动画资源,别等系统回收
}
}
动画页本身就是一个普通 ArkTS 页面,拿到 formRect 后按真实尺寸布局,用 ArkUI 动画做出框效果。出框范围有系统上限 :requestOverflow 的比例参数会被上下限裁剪(官方示例里就是 Math.min/Math.max 夹取),不同卡片规格的最大溢出比例不同,具体数值以官方文档为准。V哥的经验判断是:出框元素宜"单边或双边"破框、动效时长克制,卡片是桌面的一部分,不是全屏剧场。
四、V哥的判断:哪些业务值得做,哪些是浪费配额
互动卡片是需要申请的能力,激活态要拉起独立 ExtensionAbility,渲染成本也比普通卡片高。V哥给一个自创的判断标准------"动作---反馈"是否成立:
值得做的三类:
- 状态突变类:快递到达、取餐完成、闹钟响起------状态本身就是一个"事件",动画是事件的放大器。摇一摇触发天然契合:用户想知道进度,甩一下手机比解锁进应用快十倍。
- 物理隐喻类:睡眠卡片起床吹气球、音乐卡片切歌取专辑------动画在替用户完成一个心理动作("新的一天开始了")。这类动效有情感价值,是普通卡片永远给不了的。
- 高频轻交互类:切歌、翻牌、开盲盒------单次交互极短、无输入负担、可重复。摇一摇是这个场景的完美输入。
不值得做的三类(浪费配额):
- 纯信息展示类:天气、股价、新闻列表------数据靠刷新就够,激活态动画对用户没有增量价值,纯烧渲染资源。
- 低频重操作类:转账、报修、填表------用户本来就要进应用走流程,卡片动画救不了操作复杂度。
- 为了炫技而摇:没有任何业务理由,摇一下播放一段 logo 动画。用户摇两次就烦了,这种透支的是对整个卡片入口的信任。
一句话总结V哥的标准:动画要么替用户省一步操作,要么替产品传一分情绪,两者都不占,就不配占用激活态。
五、上线前自检清单
V哥把整条链路压成一张自检表:
| # | 检查项 | 挂了会怎样 |
|---|---|---|
| 1 | triggerTypes: ["shake"] 与 abilityName 配齐? |
摇一摇静默无效,无报错 |
| 2 | ExtensionAbility type 是 liveForm? |
系统创建不了实例 |
| 3 | onLiveFormCreate 里同步 loadContent? |
激活瞬间白屏 |
| 4 | 出框范围按 getFormRect 实测计算并接受系统裁剪? |
动效被截断或布局错位 |
| 5 | 降级策略:非 7.0 系统的卡片表现是否可接受? | 老机型用户体验断裂 |
| 6 | 动效时长与出框幅度是否克制? | 桌面变成剧场,用户关卡片 |
最后提醒一句:摇一摇能力仅 HarmonyOS 7.0 及以上触发,且具体表现以实际支持机型为准,发布前务必真机验证,别只跑模拟器。
收尾:卡片的下一站
回看这条链路,V哥的总结是:卡片从"信息展示位"进化成了"交互转化位"。以前卡片的价值上限是"少点几步";现在它能响应用户的物理动作、能跑动画、能把元素顶出框外------它第一次有了"表情"。
代价是新增了一层架构:普通态、激活态、两套 UI、一条激活链路。V哥建议把激活态动画当作品牌资产来设计,像做开屏页一样做评审,而不是当个 widget 顺手糊。
7.0 刚发,桌面上会动的卡片还不多。谁先把"摇一摇"做成用户肌肉记忆,谁就先占住这块新桌面注意力。
参考与出处
本文涉及的机制、接口与配置项来自以下官方文档:
- HarmonyOS 7 新能力一览(互动卡片:摇一摇触发静态转动态、前景元素出框)
- 互动卡片开发实践(Form Kit 最佳实践,含摇一摇七步流程与官方示例)
- 基于场景动效的互动卡片开发指导(LiveFormExtensionAbility / requestOverflow 等 API)
- ArkTS 卡片配置文件说明(sceneAnimationParams 标签,API 26 支持 triggerTypes)
最后一句:图标时代用户找你的功能,卡片时代功能在桌面上等你,互动卡片时代是用户甩一下手机、你的功能自己"活"过来------把激活态当成你的产品在桌面上的一次表演,别把它做成一段没人看的背景视频。