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

鸿蒙中 卡片交互:message事件(三)

本文同步发表于我的微信公众号,微信搜索程语新视界即可关注,每个工作日都有文章更新

之前介绍了router事件(页面跳转)和call事件(后台服务),今天聊聊第三种事件类型——message事件

message事件是卡片开发中最常用的事件类型,适用于:

  • 点击卡片按钮刷新数据

  • 卡片与应用之间的消息通信

  • 触发应用后台更新卡片内容

一、message事件

message事件是postCardAction接口支持的一种事件类型,用于卡片向卡片提供方应用发送消息

message事件的工作流程

卡片点击 │ ▼ postCardAction({ action: 'message', params: {...} }) │ ▼ 系统拉起FormExtensionAbility(如果未运行) │ ▼ 触发FormExtensionAbility的onFormEvent生命周期回调 │ ▼ 在onFormEvent中处理消息、获取新数据 │ ▼ 调用updateForm接口刷新卡片 │ ▼ 卡片收到新数据,更新显示

三种事件对比

事件类型目标作用适用场景
routerUIAbility(前台)页面跳转点击卡片进入应用详情页
callUIAbility(后台)后台服务调用音乐播放控制、后台任务
messageFormExtensionAbility消息传递数据刷新、状态同步

message事件的特点

  • 目标是FormExtensionAbility(卡片扩展能力)

  • 主要用于触发数据刷新

  • 不会显示UI界面

二、代码示例:点击按钮刷新卡片

2.1 卡片页面布局

// entry/src/main/ets/updatebymessage/pages/UpdateByMessageCard.ets // 创建LocalStorage用于数据共享 let storageUpdateByMsg = new LocalStorage(); @Entry(storageUpdateByMsg) @Component struct UpdateByMessageCard { // 通过LocalStorageProp接收卡片提供方推送的数据 // 初始值为资源文件中的默认值 @LocalStorageProp('title') title: ResourceStr = $r('app.string.default_title'); @LocalStorageProp('detail') detail: ResourceStr = $r('app.string.DescriptionDefault'); build() { Column() { // 上半部分:标题和详情显示区域 Column() { Text(this.title) .fontColor('#FFFFFF') .opacity(0.9) .fontSize(14) .margin({ top: '8%', left: '10%' }) Text(this.detail) .fontColor('#FFFFFF') .opacity(0.6) .fontSize(12) .margin({ top: '5%', left: '10%' }) } .width('100%') .height('50%') .alignItems(HorizontalAlign.Start) // 下半部分:刷新按钮 Row() { Button() { Text($r('app.string.update')) .fontColor('#45A6F4') .fontSize(12) } .width(120) .height(32) .margin({ top: '30%', bottom: '10%' }) .backgroundColor('#FFFFFF') .borderRadius(16) .onClick(() => { // 点击按钮时,通过postCardAction发送message事件 postCardAction(this, { action: 'message', params: { msgTest: 'messageEvent' // 自定义消息参数 } }); }) } .width('100%') .height('40%') .justifyContent(FlexAlign.Center) } .width('100%') .height('100%') .alignItems(HorizontalAlign.Start) .backgroundImage($r('app.media.CardEvent')) .backgroundImageSize(ImageSize.Cover) } }

说明

字段说明
@LocalStorageProp接收卡片提供方推送的数据,用于UI更新
action: 'message'指定事件类型为message
params自定义消息参数,可在FormExtensionAbility中获取

2.2 导入所需模块

// entry/src/main/ets/entryformability/EntryFormAbility.ts import { formBindingData, FormExtensionAbility, formProvider } from '@kit.FormKit'; import { Configuration, Want } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; const TAG: string = 'EntryFormAbility'; const DOMAIN_NUMBER: number = 0xFF00;

2.3 实现FormExtensionAbility

// entry/src/main/ets/entryformability/EntryFormAbility.ts export default class EntryFormAbility extends FormExtensionAbility { // 处理卡片发送的message事件 onFormEvent(formId: string, message: string): void { hilog.info(DOMAIN_NUMBER, TAG, `FormAbility onFormEvent, formId = ${formId}, message: ${message}`); // 定义新数据结构,必须与卡片布局中的字段对应 class FormDataClass { title: string = 'Title Update.'; // 新标题 detail: string = 'Description update success.'; // 新详情 } // 创建新数据 let formData = new FormDataClass(); let formInfo: formBindingData.FormBindingData = formBindingData.createFormBindingData(formData); // 调用updateForm刷新卡片 formProvider.updateForm(formId, formInfo) .then(() => { hilog.info(DOMAIN_NUMBER, TAG, 'FormAbility updateForm success.'); }) .catch((error: BusinessError) => { hilog.error(DOMAIN_NUMBER, TAG, `Operation updateForm failed. Cause: ${JSON.stringify(error)}`); }); } // 其他生命周期方法(可选) onAddForm(want: Want): formBindingData.FormBindingData { // 添加卡片时的初始化数据 let obj: Record<string, string> = { 'title': 'Initial Title', 'detail': 'Initial Description' }; return formBindingData.createFormBindingData(obj); } onUpdateForm(formId: string): void { // 定时刷新触发(如果有配置) hilog.info(DOMAIN_NUMBER, TAG, 'onUpdateForm'); } onRemoveForm(formId: string): void { // 卡片移除时清理资源 hilog.info(DOMAIN_NUMBER, TAG, 'onRemoveForm'); } }

说明

方法/字段说明
onFormEventmessage事件触发时的回调
formId触发事件的卡片ID
message卡片发送的消息内容(即params的JSON字符串)
updateForm更新卡片数据的接口
FormDataClass数据结构必须与卡片中的@LocalStorageProp字段对应

2.4 配置资源文件

// entry/src/main/resources/zh_CN/element/string.json { "string": [ { "name": "default_title", "value": "Title default." // 默认标题 }, { "name": "DescriptionDefault", "value": "Description default." // 默认描述 }, { "name": "update", "value": "刷新" // 按钮文字 } ] }

三、运行效果

状态标题描述
初始状态Title default.Description default.
点击刷新后Title Update.Description update success.

四、参数传递

4.1 卡片发送复杂参数

// 卡片中发送带多个参数的消息 postCardAction(this, { action: 'message', params: { type: 'refresh', userId: '12345', timestamp: Date.now(), config: { autoRefresh: true, interval: 3000 } } });

4.2 FormExtensionAbility接收参数

onFormEvent(formId: string, message: string): void { // message是params对象的JSON字符串 hilog.info(0xFF00, TAG, `原始消息: ${message}`); // 解析JSON字符串为对象 try { let params = JSON.parse(message); let type = params.type; // 'refresh' let userId = params.userId; // '12345' let timestamp = params.timestamp; // 时间戳 let config = params.config; // { autoRefresh: true, interval: 3000 } hilog.info(0xFF00, TAG, `type: ${type}, userId: ${userId}`); // 根据参数执行不同逻辑 if (type === 'refresh') { this.refreshUserData(formId, userId); } } catch (error) { hilog.error(0xFF00, TAG, `解析消息失败: ${error}`); } } private refreshUserData(formId: string, userId: string) { // 获取用户数据... let userData = this.fetchUserData(userId); // 更新卡片 let formData = formBindingData.createFormBindingData({ 'title': userData.name, 'detail': userData.status }); formProvider.updateForm(formId, formData); }

五、与主动刷新的对比

5.1 触发方式对比

刷新方式触发方触发时机适用场景
主动刷新应用自身数据变化时后台数据更新、推送消息
message事件卡片用户用户点击时用户手动刷新、交互操作

5.2 代码对比

// 主动刷新:应用自己调用 formProvider.updateForm(formId, formData); // message事件:卡片触发,应用响应 // 卡片中 postCardAction({ action: 'message' }); // 应用中 onFormEvent() { // 处理并调用updateForm formProvider.updateForm(formId, formData); }

六、注意事项

限制项说明
FormExtensionAbility生命周期被拉起后仅能存在5秒,需在此时间内完成操作
数据大小符合卡片刷新限制(API 20+ 10MB/20张图片)
参数格式message是JSON字符串,需要自行解析
http://www.jsqmd.com/news/487659/

相关文章:

  • 工作总结-接口设计
  • 西门子smart 200 rtu方式通讯四台三菱E700变频器资料 硬件:smart plc...
  • ChatGPT 引言写作指南:从新手到高手的结构化方法
  • YOLO系列算法改进 | 主干改进篇 | 替换ParameterNet参数优先网络 | 利用动态卷积自适应调整卷积核,助力模型低光照下增强边缘响应 | CVPR 2024
  • 永磁同步电机矢量控制FOC仿真:id=0与MTPA两种控制策略的对比分析与参考文献
  • P2679 [NOIP 2015 提高组] 子串
  • 3-16午夜盘思
  • 深入探究:直流电机单双闭环调速系统仿真模型与参数优化设计报告
  • XSLT快速入门:XML转换全攻略
  • 【论文精读】CodeWMBench 揭示 AI 生成代码水印的残酷真相
  • AudioSeal Pixel Studio从零开始:Windows平台Anaconda环境完整配置流程
  • TB6612FNG直流电机驱动板原理图设计,已量产
  • 工业级隔离型RS485接口电路原理图设计,已量产
  • 孙珍妮AI形象生成镜像指南:Z-Image-Turbo LoRA模型安全加载与沙箱隔离配置
  • Cosmos-Reason1-7B企业应用:化工厂监控视频中识别泄漏源与扩散模拟建议
  • 探索COMSOL中的Merging off-gamma BIC计算
  • std::process::Command
  • 用M文件在Matlab 2019a中实现两电平三相SVPWM
  • 乐高兼容ESP32对讲机:模块化嵌入式音频通信设计
  • 旋转卡壳
  • 基于Simulink的固定频率滞环电流控制Boost变换器
  • 南北阁Nanbeige 4.1-3B行业方案:数据库课程设计智能辅导系统
  • HCIP第二次作业
  • YOLOv8训练Visidron小目标检测数据集及精度提升实践
  • Phi-4-reasoning-vision-15B应用场景:工业质检报告截图→缺陷类型/位置/等级三字段结构化
  • 南北阁 4.1-3B 部署案例:中小团队低成本构建私有化AI对话系统的落地路径
  • COMSOL 重现基于 THz 超构表面 BIC
  • AudioSeal Pixel Studio代码实例:Python调用PyTorch实现水印生成与识别
  • 手把手教你学Simulink——基于Simulink的主从式多机器人协同搬运控制仿真
  • 《创业之路》-904- 人间清醒:故事在开始时,结局就已注定——从“党指挥枪”到华为“力出一孔”,破解组织分裂的千年宿命