Form Kit(卡片开发服务)学习笔记03-卡片UI开发与数据更新

Form Kit(卡片开发服务)笔记03:卡片UI开发与数据更新

开发HarmonyOS卡片时,UI渲染与数据更新是核心需求。卡片运行时独立于应用进程,数据更新必须通过FormProvider、FormLink、LocalStorage三者协同完成。本文梳理卡片UI开发的基本模板,以及定时刷新、事件触发刷新、本地存储通信和事件回传的具体实现。

核心概念

卡片UI基于ArkUI声明式框架,使用@Component装饰器定义组件结构。卡片运行在独立进程中,数据更新无法像普通页面那样直接绑定状态变量,需要显式触发同步机制。

FormKit提供以下数据更新机制:

  • 定时刷新:通过配置文件设定更新周期(最小值5分钟)
  • 事件触发刷新 :通过FormProvider.updateForm()接口主动推送数据
  • 本地存储通信LocalStorage实现卡片与Provider进程间数据共享
  • FormLink通信:通过跨进程通道将事件回传至Provider

核心实现

卡片UI基础模板

卡片入口文件必须用@Entry@Component修饰,常规做法是在widget/pages/目录下创建.ets文件。以下模板演示了如何展示数据并添加一个刷新按钮。

typescript 复制代码
// widget/pages/WidgetIndex.ets
@Entry
@Component
struct WidgetCard {
  @LocalStorageProp('data') data: string = '默认数据';

  build() {
    Column() {
      Text(this.data)
        .fontSize(16)
        .fontColor('#FFFFFF')
      Button('点击刷新')
        .onClick(() => {
          postCardAction(this, {
            action: 'message',
            data: { type: 'refresh' }
          });
        })
    }
    .width('100%')
    .height('100%')
  }
}

注意@LocalStorageProp必须使用与Provider端LocalStorage中相同的key才能建立绑定。postCardAction的第一个参数是this,第二个参数是Action对象,action: 'message'表示向Provider发送自定义消息。

定时刷新配置

module.json5forms块中配置updateDuration,单位为分钟,最小值5分钟。如果希望更频繁更新,需要在Provider端通过事件触发刷新。

json 复制代码
{
  "forms": [
    {
      "name": "Widget",
      "updateDuration": 30,  // 单位分钟,最小值5
      "supportDimensions": ["1*2"],
      "defaultDimension": "1*2"
    }
  ]
}

注意updateDuration配置项只对@Form形式的定时刷新生效,且必须与formName一致。实际更新周期受系统调度影响,不会严格等于配置值。

事件触发刷新(Provider端)

当需要立即更新卡片数据时,调用formProvider.updateForm()方法。通常在主应用的Ability或服务中触发。

typescript 复制代码
// 在Provider Ability中
import formProvider from '@ohos.app.form.formProvider';

function refreshCard(formId: string, data: Record<string, Object>) {
  try {
    formProvider.updateForm(formId, {
      formData: data
    }).then(() => {
      console.info('卡片数据更新成功');
    }).catch((err: BusinessError) => {
      console.error('卡片数据更新失败', err);
    });
  } catch (err) {
    console.error('更新异常', err);
  }
}

注意formId必须是从系统获取到的有效卡片ID,每次刷新都需要携带完整的数据对象(之前的数据不会被保留,需要完全覆盖)。

LocalStorage数据流转

Provider端调用localStorage.setItem()将数据写入本地存储,卡片端通过@LocalStorageProp@LocalStorageLink读取。需要注意的是,LocalStorage实例需要在卡片创建时与Provider绑定。

typescript 复制代码
// Provider写入
localStorage.setItem('data', JSON.stringify(newData));

// 卡片读取
@LocalStorageProp('data') data: string = '';

注意 :LocalStorage的key必须与卡片组件中@LocalStorageProp('key')的key一致。如果数据是复杂对象,序列化时建议使用JSON格式,卡片端再反序列化。

FormLink事件闭环

卡片通过postCardAction将用户操作回传给Provider,Provider在onFormEvent中接收并处理。以下示例中,卡片点击刷新按钮后发送message事件,Provider根据接收到的type执行对应逻辑。

typescript 复制代码
// 卡片端
postCardAction(this, {
  action: 'message',
  data: { type: 'refresh' }
});

// Provider Ability中处理事件
onFormEvent(formId: string, message: string) {
  const data = JSON.parse(message);
  if (data.type === 'refresh') {
    // 执行数据刷新逻辑
    refreshCard(formId, { data: '最新数据' });
  }
}

以上涵盖了卡片UI开发与数据更新的主要环节。实际项目中,需要根据业务场景选择定时刷新或事件触发刷新,并注意LocalStorage和FormLink的配合使用。如果对Form Kit的其他机制有疑问,欢迎在评论区交流。

Provider写入与卡片读取的数据同步,是卡片开发中的常见问题。下面给出正确的数据读写实现方式,以及卡片事件闭环的处理方法。

typescript 复制代码
// Provider写入
localStorage.setItem('data', JSON.stringify(newData));

// 卡片读取
@LocalStorageProp('data') data: string = '';

LocalStorageProp仅用于卡片侧读取已推送的数据,Provider端修改LocalStorage后必须通过formProvider.updateForm触发UI更新。直接修改LocalStorage不会反映到卡片上。

FormLink事件闭环

卡片通过postCardAction将操作回传Provider,参数action固定为'message'

typescript 复制代码
postCardAction(this, {
  action: 'message',
  data: { actionType: 'click', value: 'xxx' }
});

Provider在onFormEvent回调中解析data字段,根据actionType进行业务处理:

typescript 复制代码
onFormEvent(formId: string, message: Record<string, Object>) {
  if (message.actionType === 'click') {
    // 处理点击事件
  }
}

注意:postCardAction中的action如果误设为'router'会导致无响应,排查时可先打印message参数确认通信是否正常。

注意事项

  1. updateDuration取值范围5-180分钟,超出范围自动截断
  2. 卡片数据更新频率受系统功耗管控,频繁更新可能被静默降频
  3. @LocalStorageProp不能与@State混用
  4. 卡片进程独立,不可直接调用页面级布局方法

常见问题 FAQ

Q:卡片配置了定时刷新但未触发?

A:检查module.json5updateDuration是否大于等于5,且卡片处于可见状态

Q:postCardAction调用无反应?

A:确认卡片与Provider进程通信正常,action参数使用message而非router

Q:LocalStorage数据不同步?

A:Provider端必须通过formProvider.updateForm推送数据,直接修改LocalStorage不会触发UI更新


上一篇介绍了卡片基础配置与创建流程,下一篇将讲解卡片生命周期回调与状态管理。关于卡片数据同步与事件闭环的实现,欢迎在评论区提问交流。

相关推荐
枫叶丹439 分钟前
MCP、A2A、AG-UI:一篇讲清 Agent 协议栈
人工智能·ui·chatgpt·agent·codex
_Narcissus_1 小时前
排序算法总结表格
c语言·数据结构·c++·笔记·算法·排序算法·总结
新手unity自用笔记1 小时前
unity基于Socket的网络学习
网络·网络协议·学习·unity·c#·游戏引擎
zyf1044161 小时前
暑期实践日志 Day32:完成第六章字幕添加,推进工作
学习·计算机网络·剪辑·暑期实践·课题任务
小雪崩1 小时前
嵌入式学习 day27:标准IO
linux·c语言·学习
hsjiasb1 小时前
FreeRTOS学习(三十五)——系统架构综合项目
学习·学习笔记·freertos
YM52e2 小时前
语言地区选择器-鸿蒙ArkTS国际化页面设计
学习·华为·harmonyos
不是光头 强2 小时前
Java 后端 AI 技术选型与学习路线
java·人工智能·学习
cloudification2 小时前
virtual
学习
MartinYeung53 小时前
[论文学习]δ-STEAL:基于本地差分隐私的大语言模型窃取攻击
网络·学习·语言模型