鸿蒙中 卡片的刷新方式:主动刷新
本文介绍了ArkTS卡片主动刷新的两种实现方式:1.单卡片刷新:通过卡片按钮触发postCardAction发送事件,FormExtensionAbility接收onFormEvent后调用updateForm更新数据;2.批量刷新(API22+):在UIAbility中调用reloadForms/reloadAllForms触发onUpdateForm回调,实现多卡片同时更新。两种方式都需确保数
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
ArkTS卡片主动刷新分为两种场景:
-
卡片提供方主动刷新:应用自己触发卡片更新
-
卡片批量刷新:一次性更新多张卡片(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 批量刷新版本要求
-
reloadForms和reloadAllForms:API version 22+ -
低版本需要使用其他方式实现批量更新
4.3 权限限制
-
只能刷新自己的卡片
-
批量刷新接口只能在UIAbility中调用
ArkTS卡片的主动刷新机制:
-
单卡片刷新:通过
postCardAction+onFormEvent+updateForm实现 -
批量刷新:通过
reloadForms/reloadAllForms+onUpdateForm实现
核心流程:
-
卡片发送事件 → 提供方接收事件 → 提供方推送新数据 → 卡片更新显示
更多推荐




所有评论(0)