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的情况,欢迎在评论区留下具体错误日志,一起定位问题。

相关推荐
HwJack2011 小时前
HarmonyOS批量数据与性能优化实战:万条数据入库与不卡 UI 的查询
ui·性能优化·harmonyos
彧azz12 小时前
图的存储结构详解:邻接矩阵的原理、实现与应用
开发语言·数据结构·学习·php
平头哥AI12 小时前
Day 22 _ 包装错误别丢链_%w、errors.Is 与 errors.As
android·服务器·学习·golang·go
一阵寒风12 小时前
CAM智能化助力PCB 智能制造-培训体系第六章.项目开发学习
学习·制造
传奇开心果编程13 小时前
【Xilem 0.4 基础语法学与练】第15课:状态管理与 memoize 性能优化
学习·rust·前端框架
具身AGI13 小时前
视频即仿真,物理AI 人类学习路线 的下一步
人工智能·学习
FrameNotWork13 小时前
HarmonyOS应用《左右相册》 隐私防窥实战:用 dlpAntiPeep 让相册“感知“正在被偷瞄
华为·harmonyos
wuyk55514 小时前
从零吃透 MQTT 通信|第 8 章 FreeRTOS 多任务架构下 MQTT 工程架构,任务拆分、队列解耦、临界区保护
c语言·开发语言·stm32·学习·架构
陈年老古董15 小时前
PyTorch食物图像分类实战:从数据集制作到CNN模型训练全流程详解
pytorch·深度学习·学习·机器学习·分类·cnn