鸿蒙APP卡片与主页的设计如何协同

0 阅读7分钟

1、从透明萌宠到系统深度交互

在 HarmonyOS 6.1 的生态中,桌面卡片(Form)早已不是简单的信息展示工具,它成为了应用与用户之间最轻量、最高频的交互触点。尤其当透明卡片、待机屏保卡片等新能力开放后,卡片甚至可以承载一只“桌面萌宠”——它不再是功能组件,而是一个有生命感、可陪伴的数字角色。

然而,很多开发者(尤其是个人开发者)在初次接触卡片开发时,往往会陷入一个误区:把卡片当作主页的延伸,甚至试图用卡片替代主页。实际上,在鸿蒙的设计体系中,卡片与主页(UIAbility)各司其职,通过清晰的角色划分和标准化的交互协议,共同构成完整的应用体验

本文将结合“灵境萌伴”这一桌面萌宠应用的实战经验,深入剖析卡片与主页的设计分工、交互模式以及与系统的底层调用机制,帮助开发者建立正确的卡片开发思维。

2、卡片与主页:互补而非替代

2.1 各自的核心职责

| 组件 | 所在层级 | 核心职责 | 典型场景 |

| 卡片(Form) | 系统桌面/锁屏 | 轻量展示、高频触点、快速交互 | 查看萌宠状态、播放简单动画、触发快捷动作 |

| 主页(UIAbility) | 应用独立窗口 | 完整功能、复杂设置、数据管理 | 自定义宠物外观、购买道具、查看统计数据 |

通俗地说:卡片是“橱窗”,主页是“后场”。用户路过橱窗被吸引,点一下就可以互动;但如果想换个衣服、改个颜色,就需要走进后场(打开主页)来精细调整。

2.2 为什么不能没有主页?

有些开发者在追求极致轻量时,会考虑“只做卡片,不要主页”。这在技术上确实可行(通过 terminateSelf() 让主界面一启动就关闭),但会带来三个致命问题:

  • 首次安装体验差:用户点击桌面图标,应用一闪而过,以为没装成功。

  • 无法承载复杂配置:卡片上放十几个颜色选择器?不现实也不美观。

  • 应用市场审核风险:华为应用市场明确要求应用必须具备基本的主页或功能性界面,纯卡片应用可能被拒。 因此,一个健康的卡片应用,必须包含一个极简但功能完备的主页,用来补充卡片无法完成的设置与配置。

3、卡片与主页的交互设计

3.1 卡片内的轻量交互

卡片本身运行在桌面的 FormExtensionAbility 进程中,不能直接运行复杂的业务逻辑,但可以通过 postCardAction 实现四种标准化行为: | 行为类型 | 说明 | 适用场景 |

| router | 跳转到应用主页(可携带参数) | 点击卡片“设置”按钮,进入自定义页面 |

| message | 发送事件给卡片自身 | 点击萌宠,触发一个本地动画,不跳转 |

| call | 调用后台 FormExtensionAbility 的方法 | 刷新数据、切换歌曲等 |

| launch | 启动另一个 Ability | 打开系统设置或第三方应用 |

以“卡片宠物”为例

  • 用户单击宠物 → message 事件 → 卡片播放跳跃动画并发出短促音效。

  • 用户长按卡片空白区 → router 事件 → 跳转到主页的颜色选择页,且自动定位到当前宠物的配置。

卡片上的交互必须极简、即时、容错高。切忌在卡片上做滑动、多指等复杂手势,这既违反设计规范,也会与桌面的全局手势冲突。

3.2 主页对卡片的“反向控制”

主页虽然独立运行,但可以通过 formProvider 模块主动更新已添加到桌面的卡片。这是实现“配置实时生效”的关键。

标准流程

  1. 用户在主页修改宠物毛发颜色(例如从白色改为橙色)。

  2. 主页将新颜色值存入 Preferences(本地持久化)。

  3. 主页调用 formProvider.updateForm(formId, formBindingData),将此卡片的 UI 数据刷新。

  4. 用户返回桌面,看到萌宠已经变色,无需重新添加卡片。 需要特别注意的是:updateForm 是异步操作,对于多个卡片(用户可能添加了多张同款卡片),应该遍历所有 formId 分别更新。

3.3 主页的“引导添加卡片”设计

既然不能通过代码强制添加卡片(系统 API 不开放给普通应用),最好的方式是提供明确的图文引导。在主页顶部放置一个明显的按钮:“📌 添加萌宠到桌面”,点击后通过 context.startAbility 尝试直接跳转系统卡片选择页(部分系统版本有效),同时下方附上标准操作流程图。

一个经过验证的有效做法是:首次启动时,弹出一个半屏对话框,展示一张模拟桌面的示意图,并用箭头标注“长按应用图标 → 服务卡片 → 选择萌宠”。实践证明,这种视觉化引导的成功率远高于纯文字说明。

4、与系统的底层交互机制

4.1 卡片的全生命周期

卡片的生命周期完全由系统桌面管理,与应用主进程的生命周期相互独立。其核心回调定义在 FormExtensionAbility 中:

| 回调方法 | 触发时机 | 典型操作 |

| onAddForm | 用户将卡片添加到桌面 | 初始化卡片配置、生成 FormBindingData |

| onUpdateForm | 系统定时触发或主动调用 updateForm | 刷新卡片内容(如更新倒计时数字) |

| onDeleteForm | 用户移除卡片 | 清理该卡片的本地缓存数据 |

| onFormEvent | 卡片内发送 message 事件 | 处理单击、按钮等自定义事件 |

对于“卡片宠物”这类非实时数据型卡片,我们甚至不需要开启 updateDuration 定时刷新,只需要在用户通过主页修改配置后,主动调用 updateForm 即可。这样做既省电,又避免了不必要的网络或存储操作。

4.2 透明卡片的配置与渲染

要实现一只完全融入壁纸的萌宠,必须在 form_config.json 中显式声明:


{

  "forms": [{

    "name": "pet_card",

    "transparencyEnabled": true,

    "supportDimensions": ["2*2"],

    "defaultDimension": "2*2"

  }]

}

同时,在卡片根组件的 ArkTS 代码中设置:


@Entry

@Component

struct WidgetCard {

  build() {

    Stack() {

      Image($r('app.media.pet')).width('100%').height('100%')

    }

    .backgroundColor('rgba(0,0,0,0)') // 关键:完全透明

  }

}

需要注意,透明卡片不是“完全不可见”,其非透明区域(即萌宠图形的占面积)必须大于卡片总面积的 10%,否则系统会拒绝渲染,这是为了防止恶意应用制作全透明隐藏卡片。

4.3 数据同步机制:Preferences 与 EventHub

卡片与主页分属不同进程,不能直接共享内存对象。鸿蒙提供了两种标准的数据同步方式:

  • Preferences:轻量级键值对存储,两份进程都可以读写同一文件(需指定 Context 为全局上下文)。适合存储用户设置、宠物颜色等低频变更配置。

  • EventHub:通过 emiton 实现跨 Ability 的事件通信,适合实时触发行为(如“立即刷新卡片”)。 在“卡片宠物”中,采用 Preferences 作为唯一数据源:主页修改配置后立即写入,卡片在 onAddFormonUpdateForm 时读取 Preferences 来构建界面。这样设计简单可靠,避免了事件丢失等复杂问题。

5、代码示例:卡片与主页的最小协作模型

5.1 主页中更新卡片


// pages/Index.ets

import formProvider from '@ohos.app.form.formProvider';

import preferences from '@ohos.data.preferences';
async function updatePetColor(newColor: string) {

  // 1. 保存配置

  let prefs = await preferences.getPreferences(getContext(), 'pet_config');

  await prefs.put('color', newColor);

  await prefs.flush();


  // 2. 获取所有已添加的卡片ID(可从持久化列表中获得)

  let formIds = await getFormIdList(); // 自定义方法,从本地存储读取


  // 3. 逐个更新卡片

  for (let id of formIds) {

    let formData = { color: newColor }; // 实际需构造 FormBindingData

    await formProvider.updateForm(id, formBindingData.createFormBindingData(formData));

  }

}

5.2 卡片中读取配置


// WidgetCard.ets

async aboutToAppear() {

  let prefs = await preferences.getPreferences(getContext(this), 'pet_config');

  let color = prefs.get('color', '#FFFFFF');

  this.petColor = color;

}

6、总结

通过上文的剖析,可以看到:卡片与主页之间不是主从关系,而是平等协作、各司其职的伙伴。卡片负责极致的轻量与高频触达,主页负责深度配置与管理。二者通过 postCardAction 进行跳转通信,通过 formProviderPreferences 保持状态同步,形成完整的用户体验闭环。