Harmony os 静态卡片(ArkTS + FormLink)详细介绍

静态卡片(ArkTS + FormLink)

1. 概述

在 HarmonyOS 中,服务卡片分为 动态卡片静态卡片

  • 动态卡片:支持在运行时通过 postCardAction() 交互。
  • 静态卡片:不能 调用 postCardAction(),而是通过 FormLink 组件 与应用交互。

ArkTS 卡片提供 FormLink 静态卡片交互组件,用于静态卡片内部与卡片提供方应用 之间的交互。

FormLink 支持三种事件类型:

  • router:页面跳转(拉起 UIAbility)
  • message:向 FormExtensionAbility 发送消息
  • call:后台拉起 UIAbility 执行指定方法

静态卡片的典型结构由三部分组成:

  1. EntryFormAbility.ets:卡片生命周期管理(创建、更新、事件回调)。
  2. WidgetCard.ets:卡片 UI 页面(ArkTS 编写)。
  3. form_config.json:卡片配置信息(尺寸、布局、是否静态卡片等)。

2. 创建 ArkTS 静态卡片工程

在 DevEco Studio 中:

  1. 右键工程 → New → ArkTS Card(或 Module → Service Widget)
  2. 选择使用 ArkTS 语法,填写卡片名称等基本信息。
  3. 创建完成后,工程会自动生成以下文件:
  • EntryFormAbility.ets

    • 继承 FormExtensionAbility
    • 负责卡片的创建 onAddForm、删除 onRemoveForm、更新 onUpdateForm、处理事件 onFormEvent 等。
  • WidgetCard.ets

    • ArkTS UI 页面文件
    • 使用 @Entry @Component 定义卡片 UI。
  • form_config.json

    • 描述卡片的尺寸、布局文件路径、是否为静态卡片等。
    • 比如卡片大小、卡片 ID、默认卡片等配置都在这里。

创建向导里的默认 UI 只是示例,实际开发中我们通常会删掉默认 UI,自定义 UI 和交互逻辑


3. 配置 ArkTS 卡片的配置文件(form_config.json 概念)

这里只给重要字段的含义思路(不用死记 JSON):

  • name:卡片名称,对外展示。
  • description:卡片描述。
  • type:一般为 "JS"(ArkTS 卡片也属于此类)。
  • uiSyntax:ArkTS 卡片一般为 "arkts"
  • isStatic:是否静态卡片。静态卡片必须为 true
  • src:指向 WidgetCard.ets 对应的 UI 路径。
  • supportDimensions:支持的卡片规格(例如 ["2*2"])。
  • defaultDimension:默认尺寸。

配置完成后记得点击 Finish / OK,触发构建,让卡片配置生效。


4. WidgetCard:自定义静态卡片 UI

新建 ArkTS 卡片后,WidgetCard.ets 会自带一段默认 UI。

实际开发中我们常常会:

  1. 删除默认 UI 代码;
  2. 自己用 Column/Row/Stack/Text/Image 等组件重写。

例如,我们清空默认内容后,可以这样写一个最简单的静态卡片:

ts 复制代码
@Entry
@Component
struct WidgetCard {
  build() {
    Column() {
      Text('Hello Static Widget')
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .fontColor('#333333')
        .margin(12)
    }
    .width('100%')
    .height('100%')
  }
}

5. 卡片背景设置(推荐做法)

⚠ 在 卡片(WidgetCard) 中,不能直接使用 .backgroundImage() 来设置背景图。

原因:卡片是一个轻量独立模块,不支持部分常规页面装饰能力。

正确方式 :使用 Image + Stack 实现背景效果。

5.1 资源准备

  1. 将图片放到:
    resources/base/media/ 目录下
    例如:resources/base/media/background.png
  2. resources/base/profile/media.json 中注册对应的资源 ID(DevEco 一般会自动生成)。
  3. 命名规范:
    • background.png
    • card_bg.jpg
    • BackGround.png(大写 / 奇怪字符不推荐)

5.2 背景 + 前景内容示例

tsx 复制代码
@Entry
@Component
struct WidgetCard {
  title: string = 'Keep Running'

  build() {
    Column() {
      Stack() {
        // 1. 背景图
        Image($r('app.media.background')) // 注意要和 media.json 中的 name 一致
          .width('100%')
          .height('100%')
          .objectFit(ImageFit.Cover)      // 填满卡片区域

        // 2. 前景内容
        Column() {
          Text(this.title)
            .fontColor('#c6ea96d6')
            .fontWeight(FontWeight.Bold)
            .fontSize(20)
            .margin({ left: 12, top: 12 })
        }
      }
    }
    .width('100%')
    .height('100%')
  }
}

Stack 的作用

  • 最底层放背景 Image
  • 上面叠加 Column/Row/Text 等前景内容

静态卡片不能用 onClick 直接调逻辑,而是通过 FormLink 包裹可点击区域。

6.1 router 事件:点击卡片打开应用页面

下面是一个「点击卡片跳转到应用详情页」的完整示例:

ts 复制代码
@Entry
@Component
struct WidgetCard {
  title: string = '今日学习打卡'

  build() {
    // 整个卡片区域都可点击
    FormLink({
      action: 'router',              // 跳转类型
      abilityName: 'EntryAbility',   // 目标 UIAbility
      // 可选:bundleName / moduleName,通常省略,默认当前应用
      params: {
        targetPage: 'studyDetail',   // 约定的目标页面标识
        from: 'staticWidget'
      }
    }) {
      // 内部是卡片 UI 内容
      Stack() {
        Image($r('app.media.background'))
          .width('100%')
          .height('100%')
          .objectFit(ImageFit.Cover)

        Column() {
          Text(this.title)
            .fontColor('#FFFFFF')
            .fontWeight(FontWeight.Bold)
            .fontSize(20)
            .margin({ left: 12, top: 12 })

          Text('点击查看详细学习统计')
            .fontColor('#FFFFFF')
            .opacity(0.8)
            .fontSize(14)
            .margin({ left: 12, top: 6 })
        }
      }
    }
  }
}

UIAbility 中解析参数决定跳转页面(简单示意):

ts 复制代码
// EntryAbility.ts 片段
import UIAbility from '@ohos.app.ability.UIAbility';
import type Want from '@ohos.app.ability.Want';
import window from '@ohos.window';

let targetPage: string = 'pages/Index';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want) {
    if (want.parameters && want.parameters.params) {
      try {
        const params = JSON.parse(want.parameters.params as string);
        targetPage = params.targetPage === 'studyDetail'
          ? 'pages/StudyDetail'
          : 'pages/Index';
      } catch (e) {
        console.error('parse params error', e);
      }
    }
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    windowStage.loadContent(targetPage);
  }
}

7.1 message:通知 FormExtensionAbility 刷新卡片

ts 复制代码
FormLink({
  action: 'message',
  params: {
    op: 'refresh',
    timestamp: Date.now()
  }
}) {
  Text('点击刷新卡片内容')
    .fontSize(16)
    .margin(12)
}

EntryFormAbility.ets 中:

ts 复制代码
onFormEvent(formId: string, message: string) {
  // message 是 JSON 字符串
  const payload = JSON.parse(message);
  if (payload.op === 'refresh') {
    // TODO:读取最新数据 → 调用 updateForm 更新卡片
  }
}

7.2 call:后台拉起 UIAbility 执行任务

ts 复制代码
FormLink({
  action: 'call',
  abilityName: 'EntryAbility',
  params: {
    method: 'syncFromCloud',   // UIAbility 内约定的方法名
    extraInfo: 'some data'
  }
}) {
  Text('后台同步数据')
    .fontSize(16)
    .margin(12)
}

UIAbility 内在 onCreate/onNewWant 里解析 params.method,根据不同方法名执行不同逻辑(例如:从云端同步数据、更新数据库,然后再通过 formProvider.updateForm 刷新卡片)。


8. 小结(你可以当作复习提纲)

  1. 静态卡片交互入口是 FormLink ,支持 router / message / call 三种事件。
  2. 静态卡片相关文件:
    • EntryFormAbility.ets:生命周期 & 事件处理
    • WidgetCard.ets:卡片 UI & FormLink
    • form_config.json:卡片配置(尺寸 / 是否静态 / UI 路径)
  3. 卡片背景不要用 .backgroundImage(),用 Stack + Image 实现。
  4. router:点击卡片跳转应用页面(最常用)。
  5. message:告诉 FormExtensionAbility 做数据刷新,仅改卡片。
  6. call:在后台拉起 UIAbility 执行任务,不切到前台。
相关推荐
用户47949283569151 小时前
Bun 卖身 Anthropic!尤雨溪神吐槽:OpenAI 你需要工具链吗?
前端·openai·bun
p***43481 小时前
前端在移动端中的网络请求优化
前端
g***B7381 小时前
前端在移动端中的Ionic
前端
遇到困难睡大觉哈哈2 小时前
Harmony os——ArkTS 语言笔记(四):类、对象、接口和抽象类
java·笔记·spring·harmonyos·鸿蒙
拿破轮2 小时前
使用通义灵码解决复杂正则表达式替换字符串的问题.
java·服务器·前端
whltaoin2 小时前
【 Web认证 】Cookie、Session 与 JWT Token:Web 认证机制的原理、实现与对比
前端·web·jwt·cookie·session·认证机制
Aerelin2 小时前
爬虫playwright入门讲解
前端·javascript·html·playwright
5***o5003 小时前
前端在移动端中的NativeBase
前端
灵魂学者3 小时前
Vue3.x —— 父子通信
前端·javascript·vue.js·github