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更新


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

相关推荐
不羁的木木1 小时前
Form Kit(卡片开发服务)学习笔记02-环境搭建与基础配置
笔记·学习·harmonyos
土狗TuGou1 小时前
SQL内功笔记 · 第5篇:SQL逻辑执行顺序
数据库·笔记·后端·sql·mysql
祭曦念1 小时前
ArkUI声明式UI入门:从XML到声明式的思维转变
xml·ui·鸿蒙
Zklys1 小时前
Cmake的学习笔记step1
c++·笔记·学习
库奇噜啦呼1 小时前
【iOS】源码学习-分类、扩展、关联对象
学习·ios·分类
飞翔中文网1 小时前
Java学习笔记之接口
java·笔记·学习
吃好睡好便好1 小时前
矩阵的左除和右除
人工智能·学习·线性代数·算法·矩阵
OBiO20131 小时前
从血清型到启动子升级——如何规避心肌 AAV 肝脏泄露?
学习
雪之下雪乃的代码日记1 小时前
认识Java中集合框架
java·开发语言·笔记