📉 前言:图标是死的,卡片是活的

  • 传统 App 图标:只是一个冷冰冰的入口。用户不点开,永远不知道里面发生了什么。
  • 万能卡片:是一个动态的窗口
  • 电商 App:直接在桌面显示“您的快递还有 500米 到达”。
  • 资讯 App:直接展示今日头条热搜。
  • 工具 App:一键打卡、一键清理。

数据表明: 拥有优质桌面卡片的 App,其用户打开率(Open Rate)和次日留存(Retention)通常能提升 20% ~ 200%。因为它把“人找服务”变成了“服务找人”。


🏗️ 一、 核心架构:卡片是如何跑起来的?

在鸿蒙 Stage 模型下,卡片本质上是一个独立的 UIAbility 的延伸,由 FormExtensionAbility 管理生命周期。

卡片运行原理图 (Mermaid):

1. 此时用户添加卡片
2. 创建卡片 Provider
3. 返回初始数据 (JSON)
4. formProvider.updateForm
5. 点击卡片按钮

用户桌面 (SystemUI)

FormExtensionAbility (后台逻辑)

数据中心 (API/本地库)

用户看到: 动态刷新的 UI

拉起主 App (MainAbility)


💻 二、 代码实战:3 步打造一个“每日金句”卡片

我们要实现一个 2x2 的卡片,每天自动刷新一句励志语录。

1. 创建卡片页面 (WidgetCard.ets)

使用 ArkTS 声明式布局,写法和普通的 App 页面一模一样。

@Entry
@Component
struct WidgetCard {
  // 接收来自 Ability 的动态数据
  @LocalStorageProp('title') title: string = '默认标题';
  @LocalStorageProp('content') content: string = '加载中...';

  build() {
    Stack() {
      // 背景图
      Image($r('app.media.card_bg'))
        .width('100%').height('100%')
        .objectFit(ImageFit.Cover)
        .borderRadius(16)

      // 内容区
      Column() {
        Text(this.title)
          .fontColor('#333')
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .margin({ bottom: 5 })

        Text(this.content)
          .fontColor('#666')
          .fontSize(12)
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
      }
      .padding(12)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%').height('100%')
    .onClick(() => {
        // 点击卡片,跳转到 App 详情页
        postCardAction(this, {
            "action": "router",
            "abilityName": "EntryAbility",
            "params": { "target": "daily_quote" }
        });
    })
  }
}

2. 编写卡片逻辑 (EntryFormAbility.ts)

这是卡片的“大脑”。你需要在这里处理卡片的创建 (onAddForm) 和定时刷新 (onUpdateForm)。

import formInfo from '@ohos.app.form.formInfo';
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';

export default class EntryFormAbility extends FormExtensionAbility {
  
  // 当用户把卡片添加到桌面时触发
  onAddForm(want) {
    // 1. 准备初始数据
    let formData = {
      "title": "今日金句",
      "content": "坚持就是胜利!"
    };
    
    // 2. 封装数据
    let bindingData = formBindingData.createFormBindingData(formData);
    
    // 3. 返回给桌面显示
    return bindingData;
  }

  // 定时刷新触发 (比如每 30 分钟)
  onUpdateForm(formId) {
    // 模拟网络请求,获取新数据
    let newData = {
      "title": "晚间思考",
      "content": "代码是写给未来的情书。"
    };
    
    let bindingData = formBindingData.createFormBindingData(newData);
    
    // 主动推送到桌面更新
    // 注意:卡片更新有频率限制(每天最多 50 次)
    this.context.updateForm(formId, bindingData).then(() => {
        console.info('卡片刷新成功');
    });
  }
}

3. 配置刷新策略 (module.json5)

你需要在配置文件中告诉系统:这张卡片多久刷一次。

"forms": [
  {
    "name": "WidgetCard",
    "isDefault": true,
    "updateEnabled": true, 
    "scheduledUpdateTime": "10:30", // 每天 10:30 固定刷新
    "updateDuration": 1, // 或者每隔 1 个单位时间刷新
    "defaultDimension": "2*2",
    "supportDimensions": ["2*2", "2*4"]
  }
]


🎨 三、 进阶技巧:如何把卡片做得“性感”?

很多开发者的卡片没人用,是因为做成了“缩小版的 App 图标”。
成功的卡片必须具备:

  1. 快照化 (Snapshot)
    不要让用户思考。直接展示结果。
  • ❌ 错误:显示“点击查看我的订单”。
  • ✅ 正确:显示“您的外卖已骑行 2km,预计 10分钟 送达”。
  1. 微交互 (Micro-interaction)
    鸿蒙卡片支持 call 事件。
    你可以在卡片上放一个“打卡”按钮,点击后不需要拉起 App,直接在后台完成打卡逻辑,然后卡片上的文字变成“已打卡”。
    这种“用完即走”的体验,用户粘性极高。
  2. 视觉统一
    ArkTS 允许复用 App 内的组件样式。确保卡片的圆角、字体、配色与系统桌面风格一致(HarmonyOS Design),否则用户会觉得突兀而把它移除。

🎯 总结

鸿蒙万能卡片不是一个简单的 Shortcut,它是 Widget (小组件) + Push (推送) + Mini App (小程序) 的结合体。

对于开发者来说,这是抢占用户桌面的最后机会。
谁能占据用户桌面的 2x4 区域,谁就拥有了用户每天几十次的被动注意力

Next Step:
检查你的 App,找出 “用户最想看,但最懒得点开看” 的一个功能(比如:每日收益、待办数量、天气预警),把它做成一张卡片。相信我,你的 DAU 会给你惊喜。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐