当前位置: 首页 > 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.gsyq.cn/news/1547979.html

相关文章:

  • 美妆博主分享:2026年适合新手的6款粉饼推荐 - 品牌测评鉴赏家
  • M2.7开源模型深度解析:Agentic-first架构与非商业许可下的工程实践
  • 工业4.0下的设备维保时间智能测算:基于时序AI与Agent自动化架构的损耗预判实战
  • 告别单调:用250+配色方案打造你的专属终端工作空间
  • 基于MC68HC908MR32的永磁同步电机正弦波驱动与死区补偿技术详解
  • 嵌入式功能安全实战:基于NXP IEC60730库的GPIO短路与Flash CRC校验
  • 杰理之USB SPK位宽设置24bit,插PC会死机【篇】
  • B站视频解析技术深度解析:多协议支持与智能缓存实现
  • 嵌入式异构多核硬件设计实战:TWR-VF65GS10开发板深度解析
  • 3步掌握OpenSlide:从零开始高效处理虚拟切片图像
  • 杭州思亿欧智能体科技有限公司靠谱么?公司综合实力深度解析 - 栗子测评
  • 考软考中项报培训班一般多少钱?哪家性价比高
  • 哈尔滨本土门窗厂家排行:适配寒地需求的实力之选 - 起跑123
  • 长沙VI设计品牌推荐
  • 3分钟极速上手:Windows上最轻量级的安卓应用安装器终极指南
  • CodeWarrior IDE编译与链接实战:从源码到可执行文件的构建全解析
  • 衡阳高口碑黄金铂金回收白银回收实体老店排行 5 家靠谱门店电话地址全收录
  • 终极Flash浏览器指南:如何在现代系统上完美运行经典Flash内容
  • Framer 3.0 高保真原型设计与落地实战指南
  • 嵌入式调试实战:从断点原理到Trace跟踪的深度解析
  • 2026年众智商学院CPPM采购支出分析与数据驱动决策怎么学?采购数据分析岗位提升路径 - 众智商学院官方
  • 三步构建OFD转PDF自动化工作流:Ofd2Pdf技术解析与实战指南
  • 文件上传正常绕过
  • 2026大模型系统化学习路线:从零基础到落地进阶全指南
  • 向量数据库Milvus 啄木鸟(Woodpecker ) - 深蓝--
  • SK-S12XDP512-A开发板硬件配置与调试实战指南
  • 亨得利官方正式辟谣:关于亨得利服务渠道不实信息的严正声明与权威公示 - 亨得利官方维修中心
  • 2026年亲测三家京东E卡回收正规平台:综合评分排行榜帮你选对不踩坑 - 鼎鼎收礼品卡回收
  • 基于NXP i.MX平台的AVB/TSN音视频网络评估实战指南
  • MC68HC711D3评估板硬件连接、跳线设置与调试避坑指南