Harmony OS 卡片能力

Harmony OS 卡片能力

注意:

  • 把 卡片 分成两种
    • 静态卡片: 不允许其他事件的触发( 只能进行整体事件触发 ), 并且需要使用 FormLink 组件包裹
    • 动态卡片: 可以触发其他事件, 但是不能使用 FromLink 来触发拉起 Ability
  • 如何设置:
    • 在卡片的设置文档内( resources -> base -> profile -> form_config.json 文件 )
    • 设置 isDynamic 选项
      • false 表示非动态卡片( 静态卡片 ) 默认值
      • true 表示动态卡片
        • 动态的类型有三种 router call message

1.router类型

router 能力 => 拉起 Ability

  • 1.1 卡片上设置一些按钮
ts 复制代码
   Button('支付').onClick(() => this.clickHandler('pay'))
   Button('拍照').onClick(() => this.clickHandler('camera'))
  • 1.2 点击按钮可以打开不同的页面
    • 可以是相同的 UIAbility 的不同页面
    • 也可以是不同 UIAbility 的不同页面
    • 问题: 卡片可以调起 UIAbility,但是无法直接控制打开哪个页面,所以要在调起 UIAbility 的时候传递参数
ts 复制代码
  // 卡片按钮事件 调起 UIAbility
  // 一定是唤起 EntryAbility, 给携带过去不同的参数( 把 Type 携带过去 ),在目标 EntryAbility 里, 解析参数, 然后打开对应的页面
  clickHandler(type: string): void {
    postCardAction(this, {
      action: 'router', // call( 首次启动的时候会触发 )
      abilityName: 'EntryAbility', // 目标 UIAbility 的名称
      params: { type }
    })
  }
ts 复制代码
// 目标 EntryAbility 解析参数, 然后打开对应的页面
// 1.设置变量 pageUrl
private cardPageUrl: string = 'pages/Index'
windowStage: window.WindowStage | null = null

// 2.接受参数--传递的参数都 want 中
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  if (want?.parameters) {
    console.log('testLog onCreate 接受参数 =>', JSON.stringify(want.parameters))
    // 解析参数, 然后设置 pageUrl,因为我直接传了url过来,所以这里直接赋值
    this.cardPageUrl = (want?.parameters?.pageUrl as string) || 'pages/Index'
  }
}

// 3.打开页面
onWindowStageCreate(windowStage: window.WindowStage): void {
  if (!this.windowStage) {
    this.windowStage = windowStage
  }
  
  windowStage.loadContent(this.cardPageUrl, (err) => {
  });
}

2.call类型

call 能力 => 首次启动会触发, 用于app在后台时操作,例如音乐播放器的上一首下一首按钮

  • 注意1:使用 call 类型 需要开启权限 ohos.permission.KEEP_BACKGROUND_RUNNING

  • 思路:

    • 卡片与UIAbility 的数据存在 LocalStorage 内(与UiAbility 中 的 storage 不同,存在不同的地方)
    • UIAbility与页面的参数传递就是通过 LocalStorage、AppStorage、globalThis 来进行的
  • 2.1 卡片上设置一些按钮

ts 复制代码
// ui

Flex({ justifyContent: FlexAlign.SpaceEvenly }) {
  Text('⏮️')
    .fontSize(22)
    .onClick(() => this.clickHandle(PlayerButtonType.PREV))
  Text(this.isSuspend ? '▶️' : '⏸️')
    .fontSize(22)
    .onClick(() => this.clickHandle(this.isSuspend ? PlayerButtonType.START : PlayerButtonType.STOP))
  Text('⏭️')
    .fontSize(22)
    .onClick(() => this.clickHandle(PlayerButtonType.NEXT))
}
  • 2.2 点击按钮的时候,给 UIAbility 传递参数
ts 复制代码
// clickHandle 事件
clickHandle(type: PlayerButtonType) {
  postCardAction(this, {
    action: 'call',
    abilityName: 'EntryAbility',
    params: {
      method: 'music',
      type,
    }
  })
}
  • 2.3 UIAbility 接受参数, 然后进行处理
    • 在 EntryAbility 内, 监听 music 事件, 然后进行处理
    • 监听的事件要跟 card 传递的 method一致
ts 复制代码
// 1.监听事件
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
  try {
    this.callee.on('music', audioHandler)
  } catch (err) {
    console.log('wuwuwu 监听 catch =>', JSON.stringify(err))
  }
}

// 2.处理数据
import { rpc } from '@kit.IPCKit';

interface IParamsType {
  type: number
  formId: string
}

function audioHandler(data: rpc.MessageSequence) {
  // 参数在 data.readString() 内
  // 获取参数
  let params = JSON.parse(data.readString()) as IParamsType
  // 处理数据
  ...
  // 处理完成数据通过 AppStorage、LocalStorage 等方式传递给 UIAbility
 AppStorage.setOrCreate('audioIndex', audioIndex)
  // 使用固定的api更新card内数据,,此数据存储在LocalStroage内,供card使用
  const formInfo = formBindingData.createFormBindingData({ audioIndex })
  formProvider.updateForm(params.formId, formInfo)
}

// 3.在card中 获取数据
@LocalStorageProp('audioIndex') audioIndex: number = 99

// 4.在card中 展示数据
Text(this.audioIndex + '')

3.message类型

message 能力 => 刷新卡片内容

  • 3.1 可以使用message拉起FormExtensionAbility,点击message类型按钮会触发FormExtensionAbility的onFormEvent生命周期,然后通过固定api更新数据,存在localStorage中,供card使用。
ts 复制代码
// 1.创建一个卡片按钮
Button('按钮').onClick(() => this.clickHandle())

// 2.卡片按钮事件,message类型的参数都能在 onFormEvent 生命周期内获取到
clickHandle() {
  postCardAction(this, {
    action: 'message',
    abilityName: 'EntryAbility',
    params: {  
      newVal: 'newVal'
    }
  })

  return null
}

// 3.FormExtensionAbility 中 onFormEvent 做数据处理
onFormEvent(formId: string, message: string) {
  console.log(formId); // 1233112323 
  console.log( message); // {"newVal":"newVal","params":{"newVal":"newVal"},"action":"message"}

  // 初始化数据
  class updateFormData {
    testVal: string = 'newVall'
  }

  // 与 call 类型一样,调用固定的api更新card内数据,,此数据存储在LocalStroage内,供card使用
  const formData = formBindingData.createFormBindingData(new updateFormData())

  formProvider.updateForm(formId, formData)
    .then((res) => {
      console.log('wuwuwu updateForm =>', res)
    })
    .catch((err: BusinessError) => {
      console.log('wuwuwu updateForm catch =>', JSON.stringify(err))
    })
}

// 4.在card中 获取数据
@LocalStorageProp('testVal') testVal: string = 'initVal'

// 5.在card中 展示数据
Text(this.testVal)

现在我也开始学习鸿蒙开发,欢迎大家一起交流学习

相关推荐
dawn6 小时前
鸿蒙ArkTS中的获取网络数据
华为·harmonyos
桃花键神6 小时前
鸿蒙5.0时代:原生鸿蒙应用市场引领开发者服务新篇章
华为·harmonyos
鸿蒙自习室6 小时前
鸿蒙多线程开发——并发模型对比(Actor与内存共享)
华为·harmonyos
JavaPub-rodert7 小时前
鸿蒙生态崛起:开发者的机遇与挑战
华为·harmonyos
帅比九日9 小时前
【HarmonyOS Next】封装一个网络请求模块
前端·harmonyos
yilylong10 小时前
鸿蒙(Harmony)实现滑块验证码
华为·harmonyos·鸿蒙
baby_hua10 小时前
HarmonyOS第一课——DevEco Studio的使用
华为·harmonyos
HarmonyOS_SDK11 小时前
融合虚拟与现实,AR Engine为用户提供沉浸式交互体验
harmonyos
- 羊羊不超越 -12 小时前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
长弓三石14 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙