• 鸿蒙HarmonyOS实战-Stage模型(开发卡片事件)


    🚀一、开发卡片事件

    HarmonyOS元服务卡片页面(Metaservice Card Page)是指在HarmonyOS系统中,用于展示元服务的页面界面。元服务是指一组提供特定功能或服务的组件,例如天气服务、音乐播放服务等。元服务卡片页面可以显示元服务的相关信息和操作选项,用户可以通过点击卡片页面上的按钮或交互元素来使用相关的元服务功能。元服务卡片页面提供了一种快速访问和使用元服务的方式,方便用户进行各种操作和任务。

    🔎1.卡片事件能力说明

    postCardAction()接口是ArkTS卡片中用于实现卡片内部和提供方应用间交互的方法。目前这个接口支持三种类型的事件:router、message和call,并且仅在卡片中可以调用。

    • router类型的事件可以用来执行页面跳转或路由切换的操作。通过指定目标路由和传递参数,可以实现页面之间的跳转或路由切换。

    • message类型的事件用于发送消息或通知给提供方应用。可以通过指定目标应用和消息内容,向提供方应用发送消息或通知。

    • call类型的事件用于调用提供方应用的函数或方法。可以通过指定目标应用、要调用的函数或方法名以及传递的参数,调用提供方应用中的函数或方法。

    postCardAction()接口仅在卡片内部可以调用,无法在提供方应用中直接调用。这个接口提供了卡片和提供方应用之间进行交互的方式,可以实现卡片的功能扩展和与提供方应用的数据交互。

    image

    🔎2.使用router事件跳转到指定UIAbility

    1、元服务界面

    @Entry
    @Component
    struct WidgetCard {
      build() {
        Column() {
          Button('功能A')
            .margin('20%')
            .onClick(() => {
              console.info('Jump to EntryAbility funA');
              postCardAction(this, {
                'action': 'router',
                'abilityName': 'EntryAbility', // 只能跳转到当前应用下的UIAbility
                'params': {
                  'targetPage': 'funA' // 在EntryAbility中处理这个信息
                }
              });
            })
    
          Button('功能B')
            .margin('20%')
            .onClick(() => {
              console.info('Jump to EntryAbility funB');
              postCardAction(this, {
                'action': 'router',
                'abilityName': 'EntryAbility', // 只能跳转到当前应用下的UIAbility
                'params': {
                  'targetPage': 'funB' // 在EntryAbility中处理这个信息
                }
              });
            })
        }
        .width('100%')
        .height('100%')
      }
    }
    

    image

    2、UIAbility接收参数

    import UIAbility from '@ohos.app.ability.UIAbility';
    import window from '@ohos.window';
    
    let selectPage = "";
    let currentWindowStage = null;
    
    export default class CameraAbility extends UIAbility {
      // 如果UIAbility第一次启动,在收到Router事件后会触发onCreate生命周期回调
      onCreate(want, launchParam) {
        // 获取router事件中传递的targetPage参数
        console.info("onCreate want:" + JSON.stringify(want));
        if (want.parameters.params !== undefined) {
          let params = JSON.parse(want.parameters.params);
          console.info("onCreate router targetPage:" + params.targetPage);
          selectPage = params.targetPage;
        }
      }
      // 如果UIAbility已在后台运行,在收到Router事件后会触发onNewWant生命周期回调
      onNewWant(want, launchParam) {
        console.info("onNewWant want:" + JSON.stringify(want));
        if (want.parameters.params !== undefined) {
          let params = JSON.parse(want.parameters.params);
          console.info("onNewWant router targetPage:" + params.targetPage);
          selectPage = params.targetPage;
        }
        if (currentWindowStage != null) {
          this.onWindowStageCreate(currentWindowStage);
        }
      }
    
      onWindowStageCreate(windowStage: window.WindowStage) {
        let targetPage;
        // 根据传递的targetPage不同,选择拉起不同的页面
        switch (selectPage) {
          case 'funA':
            targetPage = 'pages/FunA';
            break;
          case 'funB':
            targetPage = 'pages/FunB';
            break;
          default:
            targetPage = 'pages/Index';
        }
        if (currentWindowStage === null) {
          currentWindowStage = windowStage;
        }
        windowStage.loadContent(targetPage, (err, data) => {
          if (err && err.code) {
            console.info('Failed to load the content. Cause: %{public}s', JSON.stringify(err));
            return;
          }
        });
      }
    };
    

    image

    🔎3.使用call事件拉起指定UIAbility到后台

    1、元服务界面

    @Entry
    @Component
    struct WidgetCard {
      build() {
        Column() {
          Button('功能A')
            .margin('20%')
            .onClick(() => {
              console.info('call EntryAbility funA');
              postCardAction(this, {
                'action': 'call',
                'abilityName': 'EntryAbility', // 只能跳转到当前应用下的UIAbility
                'params': {
                  'method': 'funA' // 在EntryAbility中调用的方法名
                }
              });
            })
           Button('功能B')
            .margin('20%')
            .onClick(() => {
              console.info('call EntryAbility funB');
              postCardAction(this, {
                'action': 'call',
                'abilityName': 'EntryAbility', // 只能跳转到当前应用下的UIAbility
                'params': {
                  'method': 'funB', // 在EntryAbility中调用的方法名
                  'num': 1 // 需要传递的其他参数
                }
              });
            })
        }
        .width('100%')
        .height('100%')
      }
    }
    

    2、UIAbility接收参数

    import UIAbility from '@ohos.app.ability.UIAbility';
     
    function FunACall(data) {
      // 获取call事件中传递的所有参数
      console.log('FunACall param:' + JSON.stringify(data.readString()));
      return null;
    }
     function FunBCall(data) {
      console.log('FunACall param:' + JSON.stringify(data.readString()));
      return null;
    }
     
    export default class CameraAbility extends UIAbility {
      // 如果UIAbility第一次启动,在收到call事件后会触发onCreate生命周期回调
      onCreate(want, launchParam) {
          try {
              // 监听call事件所需的方法
              this.callee.on('funA', FunACall);
              this.callee.on('funB', FunBCall);
          } catch (error) {
              console.log('register failed with error. Cause: ' + JSON.stringify(error));
          }
      }
       
      // 进程退出时,解除监听
      onDestroy() {
          try {
              this.callee.off('funA');
              this.callee.off('funB');
          } catch (error) {
              console.log('register failed with error. Cause: ' + JSON.stringify(error));
          }
      }
    };
    

    不截图同上

    🔎4.通过message事件刷新卡片内容

    1、卡片页面

    let storage = new LocalStorage();
    
    @Entry(storage)
    @Component
    struct WidgetCard {
      @LocalStorageProp('title') title: string = 'init';
      @LocalStorageProp('detail') detail: string = 'init';
    
      build() {
        Column() {
          Button('刷新')
            .onClick(() => {
              postCardAction(this, {
                'action': 'message',
                'params': {
                  'msgTest': 'messageEvent'
                }
              });
            })
          Text(`${this.title}`)
          Text(`${this.detail}`)
        }
        .width('100%')
        .height('100%')
      }
    }
    

    2、卡片FormExtensionAbility

    import formBindingData from '@ohos.app.form.formBindingData';
    import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
    import formProvider from '@ohos.app.form.formProvider';
    
    export default class EntryFormAbility extends FormExtensionAbility {
      onFormEvent(formId, message) {
        // Called when a specified message event defined by the form provider is triggered.
        console.info(`FormAbility onEvent, formId = ${formId}, message: ${JSON.stringify(message)}`);
        let formData = {
          'title': 'Title Update Success.', // 和卡片布局中对应
          'detail': 'Detail Update Success.', // 和卡片布局中对应
        };
        let formInfo = formBindingData.createFormBindingData(formData)
        formProvider.updateForm(formId, formInfo).then((data) => {
          console.info('FormAbility updateForm success.' + JSON.stringify(data));
        }).catch((error) => {
          console.error('FormAbility updateForm failed: ' + JSON.stringify(error));
        })
      }
    }
    

    image

    🔎5.通过router或call事件刷新卡片内容

    🦋5.1 router

    1、卡片

    let storage = new LocalStorage();
    
    @Entry(storage)
    @Component
    struct WidgetCard {
      @LocalStorageProp('detail') detail: string = 'init';
    
      build() {
        Column() {
          Button('跳转')
            .margin('20%')
            .onClick(() => {
              console.info('postCardAction to EntryAbility');
              postCardAction(this, {
                'action': 'router',
                'abilityName': 'EntryAbility', // 只能跳转到当前应用下的UIAbility
                'params': {
                  'detail': 'RouterFromCard'
                }
              });
            })
          Text(`${this.detail}`).margin('20%')
        }
        .width('100%')
        .height('100%')
      }
    }
    

    2、UIAbility

    import UIAbility from '@ohos.app.ability.UIAbility';
    import formBindingData from '@ohos.app.form.formBindingData';
    import formProvider from '@ohos.app.form.formProvider';
    import formInfo from '@ohos.app.form.formInfo';
    
    export default class EntryAbility extends UIAbility {
      // 如果UIAbility第一次启动,在收到Router事件后会触发onCreate生命周期回调
      onCreate(want, launchParam) {
        console.info('Want:' + JSON.stringify(want));
        if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
          let curFormId = want.parameters[formInfo.FormParam.IDENTITY_KEY];
          let message = JSON.parse(want.parameters.params).detail;
          console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
          let formData = {
            "detail": message + ': onCreate UIAbility.', // 和卡片布局中对应
          };
          let formMsg = formBindingData.createFormBindingData(formData)
          formProvider.updateForm(curFormId, formMsg).then((data) => {
            console.info('updateForm success.' + JSON.stringify(data));
          }).catch((error) => {
            console.error('updateForm failed:' + JSON.stringify(error));
          })
        }
      }
      // 如果UIAbility已在后台运行,在收到Router事件后会触发onNewWant生命周期回调
      onNewWant(want, launchParam) {
        console.info('onNewWant Want:' + JSON.stringify(want));
        if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
          let curFormId = want.parameters[formInfo.FormParam.IDENTITY_KEY];
          let message = JSON.parse(want.parameters.params).detail;
          console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
          let formData = {
            "detail": message + ': onNewWant UIAbility.', // 和卡片布局中对应
          };
          let formMsg = formBindingData.createFormBindingData(formData)
          formProvider.updateForm(curFormId, formMsg).then((data) => {
            console.info('updateForm success.' + JSON.stringify(data));
          }).catch((error) => {
            console.error('updateForm failed:' + JSON.stringify(error));
          })
        }
      }
    
      ...
    }
    

    🦋5.2 call

    1、在使用postCardAction接口的call事件时,需要在FormExtensionAbility中的onAddForm生命周期回调中更新formId。

    import formBindingData from '@ohos.app.form.formBindingData'; 
    import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
    
    export default class EntryFormAbility extends FormExtensionAbility {
      onAddForm(want) {
       let formId = want.parameters["ohos.extra.param.key.form_identity"];
       let dataObj1 = {
         "formId": formId
       };
       let obj1 = formBindingData.createFormBindingData(dataObj1);
       return obj1;
     }
        
     ...
    };
    

    2、卡片界面

    let storage = new LocalStorage();
    
    @Entry(storage)
    @Component
    struct WidgetCard {
      @LocalStorageProp('detail') detail: string = 'init';
      @LocalStorageProp('formId') formId: string = '0';
    
      build() {
        Column() {
          Button('拉至后台')
            .margin('20%')
            .onClick(() => {
              console.info('postCardAction to EntryAbility');
              postCardAction(this, {
                'action': 'call',
                'abilityName': 'EntryAbility', // 只能跳转到当前应用下的UIAbility
                'params': {
                  'method': 'funA',
                  'formId': this.formId,
                  'detail': 'CallFromCard'
                }
              });
            })
          Text(`${this.detail}`).margin('20%')
        }
        .width('100%')
        .height('100%')
      }
    }
    let storage = new LocalStorage();
    
    @Entry(storage)
    @Component
    struct WidgetCard {
      @LocalStorageProp('detail') detail: string = 'init';
      @LocalStorageProp('formId') formId: string = '0';
    
      build() {
        Column() {
          Button('拉至后台')
            .margin('20%')
            .onClick(() => {
              console.info('postCardAction to EntryAbility');
              postCardAction(this, {
                'action': 'call',
                'abilityName': 'EntryAbility', // 只能跳转到当前应用下的UIAbility
                'params': {
                  'method': 'funA',
                  'formId': this.formId,
                  'detail': 'CallFromCard'
                }
              });
            })
          Text(`${this.detail}`).margin('20%')
        }
        .width('100%')
        .height('100%')
      }
    }
    

    3、UIAbility界面

    import UIAbility from '@ohos.app.ability.UIAbility';
    import formBindingData from '@ohos.app.form.formBindingData';
    import formProvider from '@ohos.app.form.formProvider';
    import formInfo from '@ohos.app.form.formInfo';
    const MSG_SEND_METHOD: string = 'funA'
     
    // 在收到call事件后会触发callee监听的方法
    function FunACall(data) {
      // 获取call事件中传递的所有参数
      let params = JSON.parse(data.readString())
      if (params.formId !== undefined) {
        let curFormId = params.formId;
        let message = params.detail;
        console.info(`UpdateForm formId: ${curFormId}, message: ${message}`);
        let formData = {
          "detail": message
        };
        let formMsg = formBindingData.createFormBindingData(formData)
        formProvider.updateForm(curFormId, formMsg).then((data) => {
          console.info('updateForm success.' + JSON.stringify(data));
        }).catch((error) => {
          console.error('updateForm failed:' + JSON.stringify(error));
        })
      }
      return null;
    }
    export default class EntryAbility extends UIAbility {
      // 如果UIAbility第一次启动,call事件后会触发onCreate生命周期回调
      onCreate(want, launchParam) {
        console.info('Want:' + JSON.stringify(want));
        try {
           // 监听call事件所需的方法
          this.callee.on(MSG_SEND_METHOD, FunACall);
        } catch (error) {
          console.log(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`)
        }
      }
      ...
    }
    

    🚀写在最后

    • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
    • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
    • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
    • 更多鸿蒙最新技术知识点,请关注作者博客:https://t.doruo.cn/14DjR1rEY

    image

  • 相关阅读:
    每日一练 | 华为认证真题练习Day119
    rails的接口查询详解
    NTP时间同步服务器设置
    Spark - Task 与 Partition 一一对应与参数详解
    主流前沿的开源监控和报警系统Prometheus+Grafana入门之旅
    图解 Google V8 # 17:消息队列:V8是怎么实现回调函数的?
    LeetCode1247
    Python开源项目周排行 2023年第36周
    文件名批量重命名与翻译的实用指南
    Python利用LCU接口实现LOL(英雄联盟)一键载入自定义天赋(符文)
  • 原文地址:https://www.cnblogs.com/shudaoshan/p/18203026