鸿蒙中 卡片页面刷新方式
本文介绍了卡片刷新的三种方式:提供方主动刷新(应用数据变化时)、使用方主动刷新(系统语言/主题变化时)和系统定时定点刷新。重点讲解了卡片与应用间的数据通信机制,强调必须使用LocalStorageProp传递数据而非直接获取上下文。文章详细说明了每种刷新方式的实现方法,包括代码示例和配置说明,并指出了优先级规则(定时刷新优先于定点刷新)。最后总结了常见问题,如权限限制、数据大小限制和图片显示异常等
·
本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、卡片刷新的三种方式
卡片刷新中的角色:
-
卡片提供方:提供卡片内容的应用(比如:天气应用)
-
卡片使用方:展示卡片的系统组件(比如:桌面)
-
卡片管理服务:系统服务,负责调度刷新
卡片刷新的三种方式:
| 刷新方式 | 触发方 | 适用场景 |
|---|---|---|
| 提供方主动刷新 | 应用自己 | 数据变化时实时更新 |
| 使用方主动刷新 | 桌面等 | 系统语言/主题变化 |
| 定时定点刷新 | 系统服务 | 周期性更新 |
备注:无论哪种刷新方式,最终都需要卡片提供方推送数据!
二、数据交互
卡片和应用之间通信:

核心接口:
-
updateForm:提供方→卡片,推送数据 -
postCardAction:卡片→提供方,发送事件
限制
// 错误:不能这样
let context = getContext(this); // 不能使用!
// 正确:必须用LocalStorageProp
@Entry
@Component
struct WidgetCard {
@LocalStorageProp('title') title: string = '';
// ...
}
为什么? 因为卡片和应用是两个独立进程,不能直接拿上下文,只能用LocalStorageProp传数据。而且数据传到卡片后,会自动变成string类型!
三、主动刷新
1. 卡片提供方主动刷新(最常用)
当应用数据变化时(比如天气变了),主动告诉卡片更新:
// EntryFormAbility.ts
import { formBindingData, formProvider } from '@kit.FormKit';
export default class EntryFormAbility extends FormExtensionAbility {
// 主动刷新方法
refreshCard(formId: string) {
// 准备新数据
let obj = {
'title': '最新天气',
'detail': '晴 25°C',
'updateTime': new Date().toLocaleString()
};
// 创建数据绑定对象
let formData = formBindingData.createFormBindingData(obj);
// 调用updateForm刷新卡片
formProvider.updateForm(formId, formData)
.then(() => console.log('刷新成功'))
.catch(err => console.error('刷新失败', err));
}
// 天气变化时调用
onWeatherChange(formId: string) {
this.refreshCard(formId);
}
}
2. 卡片使用方主动刷新(仅系统应用)
当系统语言、深浅色变化时,桌面可以主动请求刷新:
// 注意:仅系统应用可用!
import { formHost } from '@kit.FormKit';
function requestFormRefresh(formId: string) {
formHost.requestForm(formId)
.then(() => console.log('请求刷新成功'))
.catch(err => console.error('请求失败', err));
}
普通应用这个接口用不了,了解即可。
四、被动刷新(定时定点)
不需要代码触发,只要配置好,系统自动刷新!
配置文件 form_config.json
{
"forms": [
{
"name": "weather_widget",
"src": "./ets/widget/pages/WeatherWidget.ets",
"uiSyntax": "arkts",
// 开启刷新
"updateEnabled": true,
// 定时刷新:每30分钟一次(30×1分钟)
"updateDuration": 1,
// 定点刷新:每天10:30刷新
"scheduledUpdateTime": "10:30"
}
]
}
优先级规则
重要:updateDuration优先级高于scheduledUpdateTime,两者同时配置时,以updateDuration为准!
被动刷新的代码实现
// EntryFormAbility.ts
export default class EntryFormAbility extends FormExtensionAbility {
// 系统自动调用这个方法
onUpdateForm(formId: string): void {
console.log('被动刷新触发');
// 获取最新数据
let formData = formBindingData.createFormBindingData({
'title': '定时更新',
'detail': `刷新于 ${new Date().toLocaleString()}`
});
// 更新卡片
formProvider.updateForm(formId, formData);
}
}
五、完整示例
卡片UI(WidgetCard.ets)
@Entry
@Component
struct WidgetCard {
@LocalStorageProp('city') city: string = '北京';
@LocalStorageProp('weather') weather: string = '晴';
@LocalStorageProp('temp') temp: string = '25°C';
@LocalStorageProp('updateTime') updateTime: string = '';
build() {
Column() {
Text(this.city).fontSize(14).fontColor('#666')
Text(this.weather).fontSize(20).fontWeight(FontWeight.Bold)
Text(this.temp).fontSize(16)
Text(`更新: ${this.updateTime}`).fontSize(10).fontColor('#999')
Button('刷新')
.fontSize(12)
.onClick(() => {
// 点击按钮通知应用更新数据
postCardAction(this, {
action: 'message',
content: 'user_refresh'
});
})
}
.padding(12)
.width('100%')
.height('100%')
}
}
卡片提供方(EntryFormAbility.ets)
export default class EntryFormAbility extends FormExtensionAbility {
// 添加卡片时的初始化数据
onAddForm(want: Want): formBindingData.FormBindingData {
return this.buildFormData('初始化数据');
}
// 定时刷新触发
onUpdateForm(formId: string): void {
this.updateCard(formId, '定时刷新');
}
// 点击按钮触发
onFormEvent(formId: string, message: string): void {
if (message === 'user_refresh') {
this.updateCard(formId, '手动刷新');
}
}
// 统一的更新方法
private updateCard(formId: string, type: string) {
let formData = this.buildFormData(type);
formProvider.updateForm(formId, formData)
.catch(err => console.error('更新失败', err));
}
private buildFormData(type: string): formBindingData.FormBindingData {
// 这里可以从网络获取真实天气数据
return formBindingData.createFormBindingData({
'city': '北京',
'weather': '晴',
'temp': '25°C',
'updateTime': `${type} ${new Date().toLocaleTimeString()}`
});
}
}
六、踩坑
1. 权限限制
// 不要试图刷新别人的卡片
formProvider.updateForm('别人的卡片ID', data); // 无效!
// 只能刷新自己的卡片
formProvider.updateForm('自己的卡片ID', data); // 正确
2. 数据大小限制(API版本不同)
| API版本 | 数据限制 | 图片限制 |
|---|---|---|
| API 20+ | 总数据 ≤ 10MB | 图片 ≤ 20张 |
| **API 19- ** | - | 图片 ≤ 5张,每张 ≤ 2MB |
警告:超出限制的图片会显示异常,别问我怎么知道的...
常见问题汇总
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 卡片不刷新 | 忘记调updateForm | 检查onUpdateForm里有没有调用 |
| 图片显示不出来 | 超出大小限制 | 压缩图片或减少图片 |
| 刷新时间不对 | 优先级搞错了 | 检查updateDuration和scheduledUpdateTime |
| 数据没更新 | LocalStorageProp用错了 | 检查key是否一致 |
更多推荐




所有评论(0)