Form Kit(卡片开发服务)学习笔记04 - 交互事件与跳转处理
开发服务卡片时,点击卡片上的某个区域或按钮,跳转到应用内指定页面并携带参数,是高频需求。但卡片UI运行在独立进程,调用router.pushUrl等普通页面路由接口会失效。正确做法是通过postCardAction接口向宿主Ability发送Want,再由宿主负责页面路由。本文用一个可运行的示例说明完整实现流程。
环境准备
- DevEco Studio 6.1.0 及以上
- HarmonyOS SDK 6.1.0(23) 及以上

核心实现
1. 卡片UI:绑定点击事件并调用postCardAction
在卡片UI(例如WidgetCard.ets)中,使用Button或Image等组件绑定onClick回调。回调内调用postCardAction,该接口属于带"卡片能力"标记的API,只能在卡片UI中使用。
typescript
// WidgetCard.ets
@Entry
@Component
struct WidgetCard {
build() {
Column() {
Button('查看详情')
.onClick(() => {
// 注意:postCardAction 需要导入 @ohos.wantAgent
postCardAction({
action: 'router',
want: {
bundleName: 'com.example.myapp', // 替换为实际bundleName
abilityName: 'EntryAbility',
parameters: {
page: 'detail',
id: 123
}
}
});
})
.width('100%')
.height(50)
.margin({ top: 20 })
}
.width('100%')
.height('100%')
.padding(10)
}
}
注意事项 :
postCardAction的action字段必须为固定值'router'(表示路由跳转)或'message'(仅通知宿主,不跳转)。want中的bundleName和abilityName必须与module.json5中配置的Ability一致,否则不会触发任何响应。
2. 宿主Ability:解析Want并执行页面跳转
宿主应用(如EntryAbility.ts)需要重写onNewWant方法(若Ability已启动)或onCreate方法(首次启动),接收卡片传来的参数,然后使用router.pushUrl进行页面跳转。
typescript
// EntryAbility.ts
import { Ability, Want } from '@kit.AbilityKit';
import { router } from '@kit.ArkUI';
export default class EntryAbility extends Ability {
// 当卡片通过postCardAction触发时,会调用此方法
onNewWant(want: Want): void {
// 获取卡片传递的参数
const page = want?.parameters?.page as string;
const id = want?.parameters?.id as number;
if (page === 'detail') {
// 跳转到详情页面并携带参数
router.pushUrl({
url: 'pages/Detail',
params: {
id: id
}
}).catch(err => {
console.error(`Router push failed: ${JSON.stringify(err)}`);
});
}
}
// 如果卡片在Ability未启动时触发,参数在onCreate中获取
onCreate(want: Want): void {
super.onCreate(want);
// 同上解析逻辑
const page = want?.parameters?.page as string;
const id = want?.parameters?.id as number;
// 延迟执行路由,避免窗口未就绪
setTimeout(() => {
if (page === 'detail') {
router.pushUrl({
url: 'pages/Detail',
params: { id }
});
}
}, 200);
}
}
注意事项 :
onNewWant在Ability已经存在时才会触发(例如卡片已打开过应用)。如果应用进程被杀死,则首次会走onCreate。建议在两个方法中都实现参数处理逻辑,保证兼容性。另外,router.pushUrl需要在UI线程中调用,setTimeout只是一种简单延缓,更可靠的做法是在onWindowStageCreate回调后执行。
3. 配置module.json5
确保目标Ability在module.json5中声明了skills字段,允许卡片通过Want拉起。
json
// module.json5
{
"module": {
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ts",
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["action.system.home"]
}
]
}
]
}
}
注意事项
- 只有带"卡片能力 "标记的接口才能在ArkTS卡片UI界面中使用,例如
postCardAction、CanvasRenderingContext2D等。普通UI接口(如router.pushUrl、media.publishImage)在卡片内调用会报错或静默失败。 - 元服务只能使用"元服务API集",卡片开发时需注意API限制,例如某些网络接口不支持。
- 不同API版本对卡片能力的支持程度有差异,使用前务必在API参考中筛选对应版本,并查看接口页面是否显示"卡片能力"标签。
常见问题 FAQ
Q:卡片中的点击事件能否跳转到应用的指定页面?
A:可以。通过postCardAction发起want,宿主Ability接收后执行页面路由即可。注意want参数中bundleName和abilityName必须正确,parameters自定义键值用于传参。
Q:如何判断某个API是否支持在卡片中使用?
A:在API参考页面左侧筛选"API version"和"设备",若该API节点正常显示且页面内标注了"卡片能力",则支持。也可以在代码中写try-catch捕获异常,但建议提前核对文档。
Q:postCardAction在卡片点击后没有反应,可能的原因有哪些?
A:检查want中的bundleName是否与app.json5中的bundleName一致;确认abilityName大小写与模块中定义的类名完全匹配;确认宿主Ability的skills配置正确(至少包含entity.system.home和action.system.home);检查SDK版本是否支持该API。
上一篇介绍了卡片的生命周期与数据刷新机制,下一篇将讲解卡片的多实例管理与配置更新。实际开发中你可能遇到Want参数在宿主中接收为undefined的情况,欢迎在评论区留下具体错误日志,一起定位问题。