前言

播放按钮只要知道“播放”就够了,但上一首、下一首不一样。切歌动画要知道用户点的是上一首还是下一首,还要知道切换前是哪首歌。

这就是项目里保存 triggerActionsongId 的原因。

效果图

A hand-drawn doodle illustration on pure white pap

切歌动画最依赖 triggerAction:上一首和下一首看起来相似,但动画方向和上下文不能混。

音乐切歌动作效果

先看点击下一首的代码

MusicCard.ets 里下一首按钮大概是:

SymbolGlyph($r('sys.symbol.fast_forward'))
  .onClick(() => {
    this.isRequestingOverflow = true;
    ActionUtils.updateRequestOverflowState(this, this.formId, true);
    ActionUtils.playByAction(this, PlayActionType.NEXT, this.formId);
    ActionUtils.requestOverFlowWithAction(
      this,
      LiveCardScale.MUSIC_WIDTH,
      LiveCardScale.MUSIC_HEIGHT,
      LIVE_CARD_DURATION,
      'NEXT',
      this.songId
    );
  });

这段里有三件事:

  1. 标记正在请求互动区。
  2. 通知应用切到下一首。
  3. 请求展开 LiveForm,并把 NEXT 和当前 songId 带过去。

triggerAction 是什么

triggerAction 就是这次触发 LiveForm 的动作。

项目里常见值:

  • PLAY
  • PREVIOUS
  • NEXT

LiveForm 页面会根据这个值决定播放哪种动画。

为什么还要 songId

切歌动画需要旧封面。

假设现在播放歌曲 A,用户点击下一首后,应用侧会把当前歌曲改成 B。

A hand-drawn doodle illustration on pure white pap

LiveForm 如果只读取当前歌曲,只能拿到 B。它不知道 A 是谁,也就做不出“从 A 切到 B”的动画。

所以点击时要把当前 songId 带上:

ActionUtils.requestOverFlowWithAction(..., 'NEXT', this.songId)

这个 songId 代表切歌前的歌曲。

EntryFormAbility 先把动作存起来

EntryFormAbility.onFormEvent() 里:

let triggerAction: string = params.triggerAction as string || '';
let songId: string = params.songId as string || '';

if (triggerAction) {
  MusicFileStore.storeTriggerAction(this.context, triggerAction, songId);
}

this.requestOverflow(formId, widthRatio, heightRatio, duration);

注意顺序:先存动作,再展开 LiveForm。

如果先展开,再存动作,LiveForm 创建时可能读不到。

MusicLiveCardAbility 再读取

MusicLiveCardAbility.ets 里:

let actionData = MusicFileStore.getTriggerAction(this.context);
if (actionData) {
  storage.setOrCreate('triggerAction', actionData.triggerAction);
  MusicFileStore.clearTriggerAction(this.context);
}

这一步把文件里的动作放进 LocalStorage,LiveForm 页面就能拿到。

读完马上清理,避免下次误用。

previousSong 怎么来的

项目里还有:

if (actionData && (actionData.triggerAction === 'PREVIOUS' || actionData.triggerAction === 'NEXT')) {
  previousSong = await songRdbHelper.querySongById(actionData.songId);
}

如果动作是上一首或下一首,就用旧 songId 从数据库查出旧歌曲。

后面 LiveForm 页面就同时拥有:

  • previousSong:切换前歌曲。
  • currentSong:切换后歌曲。

切歌动画就有素材了。

小白可以这样记

triggerAction:告诉 LiveForm 播什么动画
songId:告诉 LiveForm 旧歌是谁
currentSong:告诉 LiveForm 新歌是谁

三者缺一个,切歌动画就不完整。

常见坑

1. 只存 NEXT,不存 songId

LiveForm 知道要切歌,但不知道旧封面是谁。

2. 读完 triggerAction 不清理

下一次打开 LiveForm,还会播放上一次动画。

3. 先 requestOverflow 再存动作

LiveForm 创建太快时,可能读不到动作。

写在最后

triggerAction 不是多余字段,它是普通卡片和 LiveForm 之间的“暗号”。

做互动动画时,小白要记住:只传结果不够,有时候还要传触发过程。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐