三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

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

【共创季稿事节】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.json的abilityName是否对上。
  3. onLiveFormCreate()是否执行。
  4. session.loadContent()路径是否正确。
  5. 页面是否写了@Entry({ useSharedStorage: true })。
  6. 页面里@LocalStorageProp字段名是否和 Ability 里一致。

写在最后

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

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

← 返回列表