Form Kit(卡片开发服务)学习笔记04-交互事件与跳转处理

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)中,使用ButtonImage等组件绑定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)
  }
}

注意事项postCardActionaction字段必须为固定值'router'(表示路由跳转)或'message'(仅通知宿主,不跳转)。want中的bundleNameabilityName必须与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界面中使用,例如postCardActionCanvasRenderingContext2D等。普通UI接口(如router.pushUrlmedia.publishImage)在卡片内调用会报错或静默失败。
  • 元服务只能使用"元服务API集",卡片开发时需注意API限制,例如某些网络接口不支持。
  • 不同API版本对卡片能力的支持程度有差异,使用前务必在API参考中筛选对应版本,并查看接口页面是否显示"卡片能力"标签。

常见问题 FAQ

Q:卡片中的点击事件能否跳转到应用的指定页面?

A:可以。通过postCardAction发起want,宿主Ability接收后执行页面路由即可。注意want参数中bundleNameabilityName必须正确,parameters自定义键值用于传参。

Q:如何判断某个API是否支持在卡片中使用?

A:在API参考页面左侧筛选"API version"和"设备",若该API节点正常显示且页面内标注了"卡片能力",则支持。也可以在代码中写try-catch捕获异常,但建议提前核对文档。

Q:postCardAction在卡片点击后没有反应,可能的原因有哪些?

A:检查want中的bundleName是否与app.json5中的bundleName一致;确认abilityName大小写与模块中定义的类名完全匹配;确认宿主Ability的skills配置正确(至少包含entity.system.homeaction.system.home);检查SDK版本是否支持该API。


上一篇介绍了卡片的生命周期与数据刷新机制,下一篇将讲解卡片的多实例管理与配置更新。实际开发中你可能遇到Want参数在宿主中接收为undefined的情况,欢迎在评论区留下具体错误日志,一起定位问题。

相关推荐
一尘之中9 小时前
从C语言底层设计到系统架构评估:软件架构知识体系全景
学习·系统架构·ai写作
不爱吃糖的程序媛9 小时前
Flutter 三方库适配鸿蒙教程
flutter·华为·harmonyos
不羁的木木10 小时前
HarmonyOS文件基础服务(Core File Kit)实战演练04-文件监听与流式读写
华为·harmonyos
sheeta199810 小时前
LeetCode 每日一题笔记 日期:2026.05.29 题目:3300. 最小元素
笔记·leetcode
中屹指纹浏览器11 小时前
2026指纹浏览器代理链路适配原理与多线路集群调度方案
经验分享·笔记
星夜夏空9911 小时前
FreeRTOS学习(4)——内存映射
数据库·学习·mongodb
不羁的木木11 小时前
ArkWeb实战学习笔记05-综合实战:构建混合应用
笔记·学习·harmonyos
橙橙笔记11 小时前
Python的学习第一部分
python·学习
bush411 小时前
嵌入式linux学习记录二
linux·运维·学习