鸿蒙原子服务卡片开发,多尺寸适配完整代码
2026/7/12 2:45:29 网站建设 项目流程

原子服务卡片是鸿蒙系统最具辨识度的特色能力之一:不用打开应用,在桌面就能直接查看核心信息、执行快捷操作,是提升应用触达率的重要入口。鸿蒙 7(API 26)进一步增强了卡片的互动能力与动效表现,支持深色模式自动适配、摇一摇动态特效、内联点击事件,开发规范也全面对齐 @kit 套件体系。

本文带你从零开发一个待办统计服务卡片,完整支持 2×2(中号)、2×4(大号)两种主流尺寸,包含卡片生命周期、数据绑定、交互事件、主动更新全流程,所有代码可直接复制运行,全程基于 API 26 官方标准规范。

一、先搞懂:原子服务卡片核心基础

1.1 什么是原子服务卡片

原子服务卡片(Widget)是嵌入在鸿蒙桌面的微型应用页面,无需启动主应用即可展示信息、执行轻量操作。它和主应用共用一套 ArkUI 技术栈,底层共享沙箱数据,开发成本极低。

鸿蒙桌面以「格」为单位,主流支持四种标准尺寸:

尺寸规格形态说明适用场景
1×2窄条形,1格宽2格高单条信息、快捷开关
2×2正方形,2格宽2格高数据统计、快捷入口
2×4竖长方形,2格宽4格高列表信息、多操作入口
4×4大正方形,4格宽4格高大屏展示、丰富交互

1.2 鸿蒙 7 卡片核心升级

  1. 互动能力增强:新增onFormEvent回调,卡片内按钮点击可直接触发数据更新,无需跳转主应用
  2. 动效原生支持:接入沉浸光感、摇一摇动态特效,和系统卡片质感统一
  3. @kit 规范对齐:全面纳入@kit.AbilityKit体系,替代旧版零散的@ohos.app.form接口
  4. 深色模式自动适配:跟随系统深浅色自动切换,无需手动编写两套样式

1.3 开发前置条件

  • SDK 版本:API 26(HarmonyOS NEXT 7.0)及以上
  • 开发工具:DevEco Studio 5.0 及以上
  • 工程模型:Stage 模型(FA 模型已淘汰,不支持新版卡片能力)
  • 核心依赖:@kit.AbilityKit(卡片生命周期与数据绑定)、@kit.ArkUI(卡片UI渲染)

二、第一步:工程配置与清单声明

卡片开发的第一步是在模块配置文件中声明卡片能力,这是新手最容易踩坑的环节,配置错误会导致桌面找不到卡片。

2.1 基础工程准备

先创建一个标准的 Stage 模型 ArkTS 工程,确认根目录build-profile.json5编译版本符合要求:

{ "app": { "compileSdkVersion": "26.0.0", "compatibleSdkVersion": "26.0.0", "targets": [{ "name": "default", "runtimeOS": "HarmonyOS" }] } }

2.2 module.json5 卡片配置

打开entry/src/main/module.json5,在extensionAbilities数组中添加卡片扩展能力配置。这是卡片的「身份证」,系统通过它识别你的应用支持卡片。

完整配置如下,关键项已加注释:

"extensionAbilities": [ { "name": "TodoFormAbility", "srcEntry": "./ets/form/TodoFormAbility.ets", "description": "$string:form_desc", "type": "form", "icon": "$media:icon", "label": "$string:form_label", "formsEnabled": true, "forms": [ { "name": "TodoCard", "displayName": "$string:form_display_name", "description": "$string:form_desc", "src": "./ets/widget/TodoCard.ets", "uiSyntax": "arkts", "window": { "designWidth": 720, "autoDesignWidth": false }, "colorMode": "auto", "formVisibleNotify": true, "isDefault": true, "updateEnabled": true, "updateDuration": 30, "defaultDimension": "2*2", "supportDimensions": ["2*2", "2*4"] } ] } ]

关键配置说明

  • type: "form":声明这是一个服务卡片扩展,必须准确填写
  • srcEntry:卡片生命周期处理类的文件路径
  • forms.src:卡片 UI 页面的 ArkTS 文件路径
  • supportDimensions:声明支持的所有尺寸,用户添加卡片时可选择
  • defaultDimension:卡片默认尺寸
  • updateDuration:自动更新周期,单位为分钟,最小 30 分钟
  • colorMode: "auto":自动跟随系统深浅色模式

三、第二步:编写卡片生命周期处理类

卡片有独立的生命周期,由FormExtensionAbility统一管理,负责卡片创建、更新、事件响应、销毁等逻辑。

新建entry/src/main/ets/form/TodoFormAbility.ets,完整代码如下:

import{FormExtensionAbility,formBindingData}from'@kit.AbilityKit';import{hilog}from'@kit.PerformanceAnalysisKit';constTAG='TodoFormAbility';exportdefaultclassTodoFormAbilityextendsFormExtensionAbility{/** * 卡片首次被添加到桌面时触发 * 初始化卡片数据 */onCreate(formId:string):void{hilog.info(0x0000,TAG,`卡片创建,ID:${formId}`);constinitData=this.buildCardData();// 绑定初始数据到卡片formBindingData.createFormBindingData(initData);}/** * 卡片更新时触发(定时更新、主动调用更新) */onUpdate(formId:string):void{hilog.info(0x0000,TAG,`卡片更新,ID:${formId}`);constnewData=this.buildCardData();// 主动更新卡片数据formBindingData.updateForm(formId,newData);}/** * 鸿蒙7新增:处理卡片内的交互事件 * 点击卡片内按钮时触发,无需跳转主应用 */onFormEvent(formId:string,message:string):void{hilog.info(0x0000,TAG,`收到卡片事件:${message}`);if(message==='refresh'){// 点击刷新按钮,重新加载数据this.onUpdate(formId);}}/** * 卡片被从桌面移除时触发 */onDestroy(formId:string):void{hilog.info(0x0000,TAG,`卡片销毁,ID:${formId}`);}/** * 构造卡片数据(模拟业务数据) * 实际项目中可从本地存储、数据库读取 */privatebuildCardData():Record<string,Object>{return{totalCount:6,doneCount:2,progress:33,todoList:['完成PersistenceV2教程','开发服务卡片','适配多尺寸','测试交互事件']};}}

核心说明

  • 所有卡片能力统一从@kit.AbilityKit导入,符合新版 @kit 开发规范
  • formBindingData是数据绑定核心,负责把业务数据和卡片 UI 字段关联
  • onFormEvent是鸿蒙 7 互动卡片的核心,卡片内点击事件直接回调到这里,实现免启动应用刷新数据

四、第三步:卡片 UI 开发 + 多尺寸适配

卡片 UI 和普通 ArkUI 页面写法基本一致,但有两个核心差异:

  1. 数据通过@Prop接收,由系统自动注入绑定
  2. 系统会自动注入formWidth/formHeight两个变量,用于判断当前尺寸,实现多尺寸适配

4.1 多尺寸适配核心思路

通过系统注入的宽高变量判断当前卡片规格,使用条件渲染展示不同布局:

  • 2×2 中号卡片:简洁展示统计数据与进度,突出核心信息
  • 2×4 大号卡片:额外展示待办列表与操作按钮,信息更丰富

4.2 完整卡片 UI 代码

新建entry/src/main/ets/widget/TodoCard.ets,完整可运行代码如下:

@Componentexportdefaultstruct TodoCard{// 系统自动注入:卡片当前宽高(单位vp),用于多尺寸判断@StateformWidth:number=0;@StateformHeight:number=0;// 数据绑定:与FormAbility中传入的key一一对应,系统自动赋值@ProptotalCount:number=0;@PropdoneCount:number=0;@Propprogress:number=0;@ProptodoList:string[]=[];/** * 判断是否为2×4大号卡片 * 高度大于400vp判定为大号 */getisLargeSize():boolean{returnthis.formHeight>400;}/** * 发送刷新事件给FormAbility */handleRefresh(){postCardAction(this,{action:'event',params:{message:'refresh'}});}/** * 点击卡片整体跳转主应用 */handleJumpApp(){postCardAction(this,{action:'router',params:{uri:'pages/Index'}});}build(){Column({space:12}){// 顶部标题栏(两种尺寸都显示)Row(){Text('待办清单').fontSize(16).fontWeight(FontWeight.Medium).layoutWeight(1);if(this.isLargeSize){Text('刷新').fontSize(13).fontColor('#0A59F7').onClick(()=>this.handleRefresh());}}.width('100%');// 统计数字区(两种尺寸都显示)Row({space:8}){Text(`${this.doneCount}`).fontSize(28).fontWeight(FontWeight.Bold).fontColor('#0A59F7');Text(`/${this.totalCount}`).fontSize(14).fontColor('#888888').margin({top:8});}.width('100%');// 进度条Progress({value:this.progress,total:100,type:ProgressType.Linear}).width('100%').height(6).color('#0A59F7').backgroundColor('#E5E7EB');// 仅大号卡片显示:待办列表if(this.isLargeSize){Column({space:8}){ForEach(this.todoList.slice(0,3),(item:string,index:number)=>{Row({space:8}){Text(index<this.doneCount?'✓':'').width(16).height(16).borderRadius(8).backgroundColor(index<this.doneCount?'#00B578':'#FFFFFF').border({width:1.5,color:'#DDDDDD'}).fontSize(10).fontColor('#FFFFFF').textAlign(TextAlign.Center);Text(item).fontSize(14).fontColor(index<this.doneCount?'#999999':'#333333').decoration({type:index<this.doneCount?TextDecorationType.LineThrough:TextDecorationType.None}).layoutWeight(1).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis});}.width('100%');})}.width('100%').margin({top:4});}}.width('100%').height('100%').padding(16).backgroundColor('#FFFFFF').borderRadius(16).onClick(()=>this.handleJumpApp());}}

代码核心说明

  1. 自动注入变量formWidthformHeight由系统自动赋值,无需手动传参,是多尺寸适配的核心依据
  2. 数据自动绑定@Prop变量名和formBindingData中的 key 一一对应,数据变化自动刷新 UI
  3. 事件交互postCardAction是卡片专用交互方法,支持event(发送事件)和router(跳转应用)两种动作
  4. 条件渲染适配:通过isLargeSize计算属性控制列表显隐,不同尺寸展示不同粒度的信息

五、主应用内主动更新卡片

除了定时自动更新,主应用内数据变化时,也可以主动触发所有卡片刷新。

在主页面Index.ets中添加更新按钮,调用更新接口:

import{formBindingData,formInfo}from'@kit.AbilityKit';import{promptAction}from'@kit.ArkUI';// 主动更新所有待办卡片asyncupdateAllCards(){try{// 获取当前应用所有已添加的卡片IDconstformIds=awaitformInfo.getFormIds();if(formIds.length===0){promptAction.showToast({message:'暂无已添加的卡片'});return;}// 构造新数据constnewData={totalCount:8,doneCount:5,progress:62,todoList:['新任务1','新任务2','新任务3','新任务4']};// 批量更新所有卡片formIds.forEach(formId=>{formBindingData.updateForm(formId,newData);});promptAction.showToast({message:`已更新${formIds.length}张卡片`});}catch(err){promptAction.showToast({message:'更新失败'});}}

六、运行验证步骤

  1. 将工程编译运行到模拟器或真机,安装主应用
  2. 回到桌面,双指向内捏合进入桌面编辑模式,点击「服务卡片」
  3. 在应用列表中找到你的应用,即可看到支持的两种尺寸卡片
  4. 分别拖拽 2×2 和 2×4 尺寸到桌面,验证布局差异
  5. 点击大号卡片的「刷新」按钮,验证互动更新是否生效
  6. 打开主应用点击更新按钮,验证主动刷新是否生效

七、新手高频踩坑与解决方案

1. 桌面找不到服务卡片

  • 原因module.json5配置错误,最常见是type没写form、文件路径写错、formsEnabled为 false
  • 解决:对照本文配置逐项核对,确保srcEntryforms.src的路径与实际文件位置完全一致

2. 卡片显示「加载失败」占位图

  • 原因:卡片 UI 代码有语法错误,或使用了卡片不支持的组件(如 TextInput、Scroll 等)
  • 解决:检查 HiLog 报错日志;卡片优先使用基础展示组件,复杂交互建议跳转主应用实现

3. 多尺寸不生效,只有一种尺寸

  • 原因supportDimensions配置格式错误,或尺寸判断逻辑阈值不合理
  • 解决:尺寸格式必须为"2*2"(星号,不是×);宽高阈值根据设备实际 vp 调整,建议用区间判断而非固定值

4. 卡片数据不更新

  • 原因@Prop变量名和数据 key 不匹配,或updateForm传入的 formId 错误
  • 解决:确保变量名与数据 key 完全一致;打印日志确认 formId 正确有效

5. 导入 FormExtensionAbility 报错

  • 原因:SDK 版本低于 API 12,或使用旧版@ohos.app.form导入
  • 解决:升级 SDK 到 26.0.0 及以上,统一从@kit.AbilityKit导入相关能力

八、总结

原子服务卡片开发的核心可以概括为「一份配置 + 一个生命周期类 + 一套自适应UI」:

  • 配置是入口,决定卡片有哪些尺寸、叫什么名字
  • 生命周期类是中枢,负责数据供给与事件处理
  • UI 层通过系统注入的宽高实现多尺寸适配,一套代码覆盖多种规格

对于新手,建议先实现 2×2 基础尺寸跑通全流程,再扩展大号尺寸与互动能力;鸿蒙 7 的互动卡片能力可以实现很多轻量操作,不用跳转应用就能完成刷新、切换等动作,大幅提升用户体验。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询