![](https://s5-media.51cto.com/ost/pc/static/noavatar.gif)
回复
作者:咸鱼
团队:坚果派
公众号:“大前端之旅”
团队介绍:坚果派由坚果创建,团队拥有8个华为HDE,3个HSD,以及若干其他领域的三十余位万粉博主运营。
首先铺垫两个基础知识:
1.为什么桌面卡片需要使用特殊机制来刷新?
2.router机制、call机制与message机制有什么不同?
接下来进入正式讲解:(本案例使用router机制,拉起FormAbility来刷新卡片内容。)
其实router机制最主要的用处还是从卡片跳转应用主体,有点类似于点击桌面图标的效果,但是因为router可以带参启跳转,能实现直接进入特定页面或者启动特定功能的效果。
router实现卡片刷新效果的机制本质上就是在跳转后由程序自动或是用户手动执行updateForm接口,以刷新卡片内容。
使用router机制刷新卡片的全流程主要分为3个阶段:
由于router机制发送给UIAbility的want中已经包含了卡片信息,因此可以不需要手动传递FormID,直接使用FormInfo接口获取formId。
案例效果展示:
案例代码:
【卡片page的代码】
let storage=new LocalStorage()
@Entry(storage)
@Component
struct WidgetCard {
@LocalStorageProp('textInfo') textInfo:string='原始文本内容'
build() {
Column() {
Text(this.textInfo)
.fontColor(Color.Black)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.onClick(() => {
postCardAction(this, {
"action": "router",
"abilityName": 'EntryAbility',
"params": {
"detail": ''
}
});
})
}
}
【Router后自动刷新的方案】
UIAbility的关键代码:
export default class EntryAbility extends UIAbility {
onCreate() {
if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
let FormId = want.parameters[formInfo.FormParam.IDENTITY_KEY];//获取formID
//let message = JSON.parse(want.parameters.params).detail;//读取入参
let formData = {
"textInfo": '卡片内容已更新', // 和卡片布局中对应
};
let formMsg = formBindingData.createFormBindingData(formData)
formProvider.updateForm(FormId, formMsg).then((data) => {
console.info('updateForm success.' + JSON.stringify(data));
}).catch((error) => {
console.error('updateForm failed:' + JSON.stringify(error));
})
}
}
onNewWant(want){
if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
let FormId = want.parameters[formInfo.FormParam.IDENTITY_KEY];//获取formID
//let message = JSON.parse(want.parameters.params).detail;//读取入参
let formData = {
"textInfo": '卡片内容已更新', // 和卡片布局中对应
};
let formMsg = formBindingData.createFormBindingData(formData)
formProvider.updateForm(FormId, formMsg).then((data) => {
console.info('updateForm success.' + JSON.stringify(data));
}).catch((error) => {
console.error('updateForm failed:' + JSON.stringify(error));
})
}
}
}
【Router后用户手动刷新的方案】
UIAbility的关键代码:
export default class EntryAbility extends UIAbility {
onNewWant(want){
if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
let FormId = want.parameters[formInfo.FormParam.IDENTITY_KEY];
//let message = JSON.parse(want.parameters.params).detail;
AppStorage.SetOrCreate('formId',FormId)//保存当前卡片的FormID
}
}
}
Page页的关键代码:
import formBindingData from '@ohos.app.form.formBindingData';
import formProvider from '@ohos.app.form.formProvider';
@Entry
@Component
struct homepage {
@State cardText: string = ''
build() {
Column(){
TextInput()
.onChange((res)=>{
this.cardText=res
})
Button('刷新卡片')
.onClick(async () => {
if (AppStorage.Has('formId')) {
let formId: string = AppStorage.Get('formId')//获取UIAbility保存的FormID
let formData = {
"textInfo": this.cardText
};
let formMsg = formBindingData.createFormBindingData(formData)
try {
await formProvider.updateForm(formId, formMsg)//刷新卡片
AlertDialog.show({
message:'卡片刷新成功'
})
}
catch (error) {//失败回调
AlertDialog.show({
message:'卡片刷新失败,错误信息:'+JSON.stringify(error)
})
}
} else {
AlertDialog.show({
message: '请先添加卡片'
})
}
})
}
.width('100%')
.height('100%')
}
}
【即1.的代码,updateForm成功后会根据LocalStorage中特定参数的变化会自动刷新】
let storage=new LocalStorage()
@Entry(storage)
@Component
struct WidgetCard {
@LocalStorageProp('textInfo') textInfo:string='原始文本内容'//localStorage变化后自动同步,更新UI
build() {
Column() {
Text(this.textInfo)
.fontColor(Color.Black)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.onClick(() => {
postCardAction(this, {
"action": "router",
"abilityName": 'EntryAbility',
"params": {
"detail": ''
}
});
})
}
}
postCardAction接口router事件的写法如下:
updateForm接口的写法如下: