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

ArkTS卡片主动刷新分为两种场景:

  1. 卡片提供方主动刷新:应用自己触发卡片更新

  2. 卡片批量刷新:一次性更新多张卡片(API 22+)

一、场景一:点击卡片按钮刷新

1.1 实现效果

卡片添加到桌面后,显示默认标题和描述。点击卡片上的"刷新"按钮,标题和描述立即更新为新内容。

1.2 开发步骤

步骤1:创建卡片布局

首先,在卡片UI中添加一个刷新按钮,并设置点击事件:

// entry/src/main/ets/updatebymessage/pages/UpdateByMessageCard.ets

// 创建LocalStorage用于数据共享
let storageUpdateByMsg = new LocalStorage();

@Entry(storageUpdateByMsg)
@Component
struct UpdateByMessageCard {
    // 接收卡片提供方推送的数据,初始值为资源文件中的默认值
    @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触发onFormEvent回调
                    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:接收提供方推送的数据

  • postCardAction:点击按钮时发送事件给提供方

步骤2:实现FormExtensionAbility

在卡片提供方中,实现onFormEvent回调,处理卡片发来的事件:

// entry/src/main/ets/entryformability/EntryFormAbility.ts

import { formBindingData, FormExtensionAbility, formInfo, 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;

export default class EntryFormAbility extends FormExtensionAbility {
    
    // 1. 添加卡片时触发
    onAddForm(want: Want): formBindingData.FormBindingData {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onAddForm');
        
        // 返回初始化数据
        let obj: Record<string, string> = {
            'title': 'titleOnAddForm',    // 对应卡片中的title
            'detail': 'detailOnAddForm'    // 对应卡片中的detail
        };
        
        return formBindingData.createFormBindingData(obj);
    }

    // 2. 处理卡片事件(重点)
    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)}`);
            });
    }

    // 其他生命周期方法(可保留默认实现)
    onCastToNormalForm(formId: string): void {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onCastToNormalForm');
    }

    onUpdateForm(formId: string): void {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onUpdateForm');
    }

    onChangeFormVisibility(newStatus: Record<string, number>): void {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onChangeFormVisibility');
    }

    onRemoveForm(formId: string): void {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onRemoveForm');
    }

    onConfigurationUpdate(config: Configuration) {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onConfigurationUpdate:' + JSON.stringify(config));
    }

    onAcquireFormState(want: Want): formInfo.FormState {
        return formInfo.FormState.READY;
    }
}
步骤3:配置资源文件
// entry/src/main/resources/zh_CN/element/string.json
{
  "string": [
    {
      "name": "default_title",
      "value": "Title default."          // 默认标题
    },
    {
      "name": "DescriptionDefault",
      "value": "Description default."    // 默认描述
    },
    {
      "name": "update",
      "value": "刷新"                     // 按钮文字
    }
  ]
}

1.3 运行结果

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

二、场景二:批量刷新多张卡片(API 22+)

从API version 22开始,支持批量刷新多张卡片。比如应用添加了多张卡片到桌面,点击应用中的一个按钮,可以同时更新所有卡片。

2.1 实现效果

  • 在桌面上添加多张同类型的卡片

  • 打开应用,点击"reloadForms"或"reloadAllForms"按钮

  • 所有卡片的内容同时刷新(标题和描述显示随机数)

2.2 开发步骤

步骤1:创建卡片布局
// entry/src/main/ets/reloadbyuiability/pages/ReloadByUIAbilityCard.ets

let storageReloadForm = new LocalStorage();

@Entry(storageReloadForm)
@Component
struct ReloadByUIAbilityCard {
    // 两个待刷新的Text,初始值为默认内容
    @LocalStorageProp('title') title: ResourceStr = $r('app.string.default_title');
    @LocalStorageProp('detail') detail: ResourceStr = $r('app.string.DescriptionDefault');

    build() {
        Column() {
            Column() {
                Text(this.title)
                    .fontSize(14)
                    .margin({ top: '8%', left: '10%' })
                
                Text(this.detail)
                    .fontSize(12)
                    .margin({ top: '5%', left: '10%' })
            }
            .width('100%')
            .height('50%')
            .alignItems(HorizontalAlign.Start)
        }
        .width('100%')
        .height('100%')
        .alignItems(HorizontalAlign.Start)
    }
}
步骤2:实现FormExtensionAbility
// entry/src/main/ets/entryformability/EntryFormAbility.ets

import { formBindingData, FormExtensionAbility, formInfo, formProvider } from '@kit.FormKit';
import { Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

const TAG: string = 'EntryFormAbility';
const DOMAIN_NUMBER: number = 0xFF00;

export default class EntryFormAbility extends FormExtensionAbility {
    
    onAddForm(want: Want) {
        // 初始化空数据
        return formBindingData.createFormBindingData('');
    }

    // 批量刷新时,系统会为每张卡片调用此方法
    onUpdateForm(formId: string) {
        // 生成随机数作为新内容
        class FormDataClass {
            title: string = 'Title: ' + Math.random();
            detail: string = 'Description: ' + Math.random();
        }

        let formData = new FormDataClass();
        let formInfo: formBindingData.FormBindingData = 
            formBindingData.createFormBindingData(formData);

        // 更新单张卡片
        formProvider.updateForm(formId, formInfo)
            .then(() => {
                hilog.info(DOMAIN_NUMBER, TAG, 'FormAbility updateForm success.');
            })
            .catch((error: BusinessError) => {
                hilog.error(DOMAIN_NUMBER, TAG, 
                    `Operation updateForm failed. code: ${error.code}, message: ${error.message}`);
            });
    }

    // 其他生命周期方法
    onCastToNormalForm(formId: string): void {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onCastToNormalForm');
    }

    onFormEvent(formId: string, message: string) {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onFormEvent');
    }

    onRemoveForm(formId: string) {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onRemoveForm');
    }

    onAcquireFormState(want: Want) {
        hilog.info(DOMAIN_NUMBER, TAG, '[EntryFormAbility] onAcquireFormState');
        return formInfo.FormState.READY;
    }
}
步骤3:在UIAbility中添加批量刷新按钮
// entry/src/main/ets/pages/index.ets

import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { formProvider } from '@kit.FormKit';

@Entry
@Component
struct Index {
    build() {
        Column({ space: 20 }) {
            // 按钮1:刷新指定类型的卡片
            Button('reloadForms')
                .onClick(() => {
                    try {
                        // 获取UIAbility上下文
                        let context: common.UIAbilityContext = 
                            this.getUIContext().getHostContext() as common.UIAbilityContext;
                        
                        // 指定要刷新的卡片信息
                        let moduleName: string = 'entry';           // 模块名
                        let abilityName: string = 'EntryFormAbility'; // Ability名
                        let formName: string = 'reloadByUIAbilityCard'; // 卡片名

                        // 调用reloadForms批量刷新
                        formProvider.reloadForms(context, moduleName, abilityName, formName)
                            .then((reloadNum: number) => {
                                console.info(`reloadForms success, 刷新了 ${reloadNum} 张卡片`);
                            })
                            .catch((error: BusinessError) => {
                                console.error(`reloadForms失败, code: ${error.code}, message: ${error.message}`);
                            });
                    } catch (error) {
                        console.error(`异常, code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message}`);
                    }
                })

            // 按钮2:刷新所有卡片
            Button('reloadAllForms')
                .onClick(() => {
                    try {
                        let context: common.UIAbilityContext = 
                            this.getUIContext().getHostContext() as common.UIAbilityContext;

                        // 调用reloadAllForms刷新所有卡片
                        formProvider.reloadAllForms(context)
                            .then((reloadNum: number) => {
                                console.info(`reloadAllForms success, 刷新了 ${reloadNum} 张卡片`);
                            })
                            .catch((error: BusinessError) => {
                                console.error(`reloadAllForms失败, code: ${error.code}, message: ${error.message}`);
                            });
                    } catch (error) {
                        console.error(`异常, code: ${(error as BusinessError).code}, message: ${(error as BusinessError).message}`);
                    }
                })
        }
        .height('100%')
        .width('100%')
        .justifyContent(FlexAlign.Center)
    }
}
步骤4:配置资源文件
// entry/src/main/resources/base/element/string.json
{
  "string": [
    {
      "name": "default_title",
      "value": "Title default."
    },
    {
      "name": "DescriptionDefault",
      "value": "Description default."
    }
  ]
}

2.3 接口说明

接口 参数 作用
reloadForms context, moduleName, abilityName, formName 刷新指定类型的卡片
reloadAllForms context 刷新所有卡片

注意

  • 这两个接口仅支持在UIAbility中调用

  • 调用后会触发对应卡片的onUpdateForm回调

  • 返回值reloadNum表示实际刷新的卡片数量

三、核心接口

3.1 卡片提供方接口

接口 作用 调用时机
updateForm 更新单张卡片 任意需要刷新时
reloadForms 批量刷新指定类型卡片 UIAbility中
reloadAllForms 批量刷新所有卡片 UIAbility中

3.2 卡片接口

接口 作用 调用方
postCardAction 发送事件给提供方 卡片

3.3 生命周期回调

回调 触发时机
onAddForm 添加卡片时
onUpdateForm 定时刷新/批量刷新时
onFormEvent 卡片发送事件时

四、注意事项

4.1 数据对应关系

// 卡片提供方推送的数据字段
let obj = {
    'title': '新标题',  // 必须与卡片中的@LocalStorageProp('title')对应
    'detail': '新详情'   // 必须与卡片中的@LocalStorageProp('detail')对应
};

4.2 批量刷新版本要求

  • reloadFormsreloadAllFormsAPI version 22+

  • 低版本需要使用其他方式实现批量更新

4.3 权限限制

  • 只能刷新自己的卡片

  • 批量刷新接口只能在UIAbility中调用

ArkTS卡片的主动刷新机制:

  1. 单卡片刷新:通过postCardAction + onFormEvent + updateForm实现

  2. 批量刷新:通过reloadForms/reloadAllForms + onUpdateForm实现

核心流程:

  • 卡片发送事件 → 提供方接收事件 → 提供方推送新数据 → 卡片更新显示

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐