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 模块主动更新已添加到桌面的卡片。这是实现“配置实时生效”的关键。
标准流程:
-
用户在主页修改宠物毛发颜色(例如从白色改为橙色)。
-
主页将新颜色值存入
Preferences(本地持久化)。 -
主页调用
formProvider.updateForm(formId, formBindingData),将此卡片的 UI 数据刷新。 -
用户返回桌面,看到萌宠已经变色,无需重新添加卡片。 需要特别注意的是:
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:通过
emit和on实现跨 Ability 的事件通信,适合实时触发行为(如“立即刷新卡片”)。 在“卡片宠物”中,采用 Preferences 作为唯一数据源:主页修改配置后立即写入,卡片在onAddForm和onUpdateForm时读取 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 进行跳转通信,通过 formProvider 和 Preferences 保持状态同步,形成完整的用户体验闭环。