当前位置: 首页 > news >正文

【共创季稿事节】HarmonyOS7 互动卡片开发实践:写一个能加载页面的最小 LiveForm Ability

文章目录

      • 效果图
      • 项目里的 LiveForm Ability 在哪里
      • 最小代码长什么样
      • onLiveFormCreate 是入口
      • 为什么要用 LocalStorage
      • session.loadContent 的路径怎么写
      • 页面必须 useSharedStorage
      • module.json5 也要注册
      • 从项目里学到的好习惯
      • 排查清单
      • 写在最后

普通卡片负责显示在桌面上,LiveForm Ability 负责加载展开后的互动页面。

这篇不讲复杂业务,先写一个最小版本,让小白知道LiveFormExtensionAbility到底干什么。

效果图

先看最终要加载出来的 LiveForm 效果。普通卡片只是入口,真正展开后的互动页面,就是由 LiveForm Ability 加载出来的。

项目里的 LiveForm Ability 在哪里

当前项目有四个:

  • entry/src/main/ets/livecardability/SleepLiveCardAbility.ets
  • entry/src/main/ets/livecardability/DeliveryLiveCardAbility.ets
  • entry/src/main/ets/livecardability/ExerciseLiveCardAbility.ets
  • entry/src/main/ets/livecardability/MusicLiveCardAbility.ets

它们的结构很像:创建LocalStorage,塞数据,调用session.loadContent()

最小代码长什么样

你可以先看这个简化版:

import{formInfo,LiveFormExtensionAbility,LiveFormInfo}from'@kit.FormKit';importUIExtensionContentSessionfrom'@ohos.app.ability.UIExtensionContentSession';exportclassDemoLiveCardAbilityextendsLiveFormExtensionAbility{onLiveFormCreate(liveFormInfo:LiveFormInfo,session:UIExtensionContentSession):void{conststorage=newLocalStorage();storage.setOrCreate('context',this.context);storage.setOrCreate('session',session);storage.setOrCreate('formId',liveFormInfo.formId);storage.setOrCreate('borderRadius',liveFormInfo.borderRadius);constrect:formInfo.Rect=liveFormInfo.rect;storage.setOrCreate('formRect',rect);session.loadContent('livecardability/pages/DemoLiveCard',storage);}}

这段就是一个能工作的 LiveForm Ability 骨架。

onLiveFormCreate 是入口

onLiveFormCreate(liveFormInfo:LiveFormInfo,session:UIExtensionContentSession):void

系统创建互动区域时,会调用这个方法。

liveFormInfo里有当前卡片的信息,比如:

  • formId
  • rect
  • borderRadius

session是加载 UI 的会话对象。你最后要通过它加载页面。

为什么要用 LocalStorage

Ability 和 ArkUI 页面不是一个普通函数调用关系。你不能直接把参数传进组件构造函数。

项目里用LocalStorage传数据:

conststorage=newLocalStorage();storage.setOrCreate('formId',liveFormInfo.formId);storage.setOrCreate('formRect',liveFormInfo.rect);

页面里再这样接:

@Entry({useSharedStorage:true})@Componentstruct DemoLiveCard{@LocalStorageProp('formId')formId:string='';@LocalStorageProp('formRect')formRect?:formInfo.Rect=undefined;}

字段名要一致。Ability 里写formRect,页面里也要写formRect

session.loadContent 的路径怎么写

session.loadContent('livecardability/pages/DemoLiveCard',storage);

注意几点:

  • 不写entry/src/main/ets
  • 不写.ets后缀。
  • 路径从ets目录下开始算。

比如项目里的音乐页面是:

entry/src/main/ets/livecardability/pages/MusicLiveCard.ets

加载时写:

session.loadContent('livecardability/pages/MusicLiveCard',storage);

页面必须 useSharedStorage

LiveForm 页面要这样写:

@Entry({useSharedStorage:true})@Componentstruct DemoLiveCard{@LocalStorageProp('formId')formId:string='';build(){Column(){Text(`formId:${this.formId}`)}.width('100%').height('100%')}}

没有useSharedStorage: true,页面拿不到 Ability 传进来的LocalStorage

这是小白很容易漏的一行。

module.json5 也要注册

写了 Ability 文件还不够,必须在module.json5注册:

{ "name": "DemoLiveCardAbility", "srcEntry": "./ets/livecardability/DemoLiveCardAbility.ets", "type": "liveForm" }

然后form_config.json里绑定:

"sceneAnimationParams":{"abilityName":"DemoLiveCardAbility"}

这两处名字必须一致。

从项目里学到的好习惯

项目里的MusicLiveCardAbility不只是加载页面,还会准备业务数据:

storage.setOrCreate('triggerAction',actionData.triggerAction);storage.setOrCreate('songList',initSongs);storage.setOrCreate('currentSong',currentSong);storage.setOrCreate('previousSong',previousSong);

也就是说,LiveForm Ability 适合做“页面打开前的数据准备”。

页面专心画 UI 和动画,不要把所有初始化逻辑都堆到页面里。

排查清单

LiveForm 页面加载不出来时,按这个顺序查:

  1. module.json5是否注册了type: "liveForm"
  2. form_config.jsonabilityName是否对上。
  3. onLiveFormCreate()是否执行。
  4. session.loadContent()路径是否正确。
  5. 页面是否写了@Entry({ useSharedStorage: true })
  6. 页面里@LocalStorageProp字段名是否和 Ability 里一致。

写在最后

LiveForm Ability 的核心不是写 UI,而是“接住系统创建事件,然后加载互动页面”。

小白可以先跑通最小版本,再慢慢加音乐列表、传感器、Canvas 动画这些复杂内容。

http://www.jsqmd.com/news/1036081/

相关文章:

  • 5分钟免费激活Windows和Office:告别激活弹窗的完整指南
  • AI应用开发面试题精讲(四):系统架构与生产落地高频15问
  • 实测合肥收金渠道:品牌金店回收隐藏门槛全曝光 - 奢侈品回收评测
  • 美妆博主分享:2026年适合新手的6款粉饼推荐 - 品牌测评鉴赏家
  • NIPAP架构解密:下一代企业级IP地址管理系统的设计哲学与范式重构
  • 2026宁波沥青铁皮回收公司 专业测评 - LYL仔仔
  • 终极暗黑3按键助手完整指南:3步配置解放双手,5大场景高效速刷
  • M2.7开源模型深度解析:Agentic-first架构与非商业许可下的工程实践
  • 思亿欧外贸联合运营怎么样?实力评估解析 - 栗子测评
  • 嵌入式调试核心技术:硬件断点与JTAG接口原理及实战配置
  • 2026年6月温州乐清市黄金回收乱象:卖金套路深,市民如何避坑?含避坑指南 - 微城市网络
  • GetQzonehistory:3步完成QQ空间完整备份的终极指南
  • Ubuntu高效终端环境搭建:Terminator+ZSH+Oh My Zsh实战指南
  • 武汉假发实体店实测!六渡桥这家超市款式全、逼真度拉满,脱发星人必逛 - 行业深度观察C
  • 工业4.0下的设备维保时间智能测算:基于时序AI与Agent自动化架构的损耗预判实战
  • GLM-5.2 只差 Claude 0.7%,国产开源终入第一梯队
  • 学习 nana c++ 库 (一)
  • Python开发工具指南:提升你的开发效率
  • 快速制作投票活动链接的最新教程,必备干货!
  • TLM2.0
  • 2026多品牌大电流微欧计实测:青岛普锐思高口碑生产商测评 - 品牌推荐大师
  • 2026武汉真人发假发定制推荐:武汉三星速美假发超市实力全盘点 - 行业深度观察C
  • 基于MC68HC908MR32的永磁同步电机正弦波驱动与死区补偿技术详解
  • NXP T4240RDB参考设计板硬件架构解析与设计实践
  • 百度网盘秒传解决方案:高效文件管理与分享终极指南
  • 外贸快车怎么样?实力测评解析 - 栗子测评
  • 如何三步快速解密Navicat数据库连接密码的完整免费解决方案
  • 终极跨平台Access数据库处理方案:MDB Tools实战指南
  • Motorola Suite56 ADS调试器:OnCE与MFAX技术深度解析与实战指南
  • 5分钟搞定Windows和Office激活:KMS智能脚本终极指南