HarmonyOS鸿蒙Next中使用transition + visibility + animateTo实现弹窗的自定义动画,无法控制弹窗收回时的速度,设置动画曲线和动画播放速度都无效

HarmonyOS鸿蒙Next中使用transition + visibility + animateTo实现弹窗的自定义动画,无法控制弹窗收回时的速度,设置动画曲线和动画播放速度都无效 在使用 transition + visibility + animateTo 实现弹窗的自定义动画时,发现无法控制弹窗收回时的速度,点击关闭弹窗时,弹窗会立马收回,这是为什么?

代码如下:

// 弹窗交互
@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample(),
    autoCancel: true
  });
  @State showFlag: Visibility = Visibility.Visible;
  build() {
    Column() {
      Row() {
        Text('自定义动画的弹窗');
      }
      .justifyContent(FlexAlign.Center)
      .padding(8)
      .backgroundColor('#FFFFFF')
      .height(100)
      .margin({ bottom: 30 })
      .width('80%')
      .borderRadius(32);
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
    .onClick(() => {
      this.cancel();
    })
    .visibility(this.showFlag)
    // 定义进场出场转场动画效果
    .transition(TransitionEffect.OPACITY.animation({ duration: 1000 })
      .combine(TransitionEffect.translate({ y: 400 })), (transitionIn: boolean) => {
        if (this.showFlag === Visibility.Hidden && transitionIn === false) {
          this.controller.close();
        }
      });
  }
  cancel() {
    this.showFlag = Visibility.Hidden;
  }
}

@Entry
@Component
struct CustomDialogUser {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample(),
    customStyle: true
  });
  build() {
    Column() {
      Button('click me')
        .onClick(() => {
          this.dialogController.open();
        });
    }
    .width('100%')
    .height('100%');
  }
}

更多关于HarmonyOS鸿蒙Next中使用transition + visibility + animateTo实现弹窗的自定义动画,无法控制弹窗收回时的速度,设置动画曲线和动画播放速度都无效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

由于通过visibility这个属性实现从下方弹出的自定义弹窗,在点击关闭弹窗的时候,visibility会改变为false,弹窗会立即收回变为不可视状态,这导致动画也会失效,所以使用visibility属性,无法控制弹窗收回动画的速度

更多关于HarmonyOS鸿蒙Next中使用transition + visibility + animateTo实现弹窗的自定义动画,无法控制弹窗收回时的速度,设置动画曲线和动画播放速度都无效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


尊敬的开发者,您好!您的问题已受理,请您耐心等待,感谢您的理解与支持

在HarmonyOS Next中,使用transition + visibility + animateTo实现弹窗动画时,若无法控制收回速度,需检查动画曲线与duration是否在animateTo的闭包内正确应用。确保visibility属性变化与动画执行同步,并确认动画参数未在组件树更新时被重置。

问题出在动画结束后的 controller.close() 调用时机上。在 transition 的回调函数中,当 showFlag 变为 HiddentransitionInfalse(表示退场动画结束时)才关闭弹窗控制器,这本身是正确的逻辑。

但弹窗“立即收回”的原因是:cancel() 方法中,你将 showFlag 设置为 Visibility.Hidden 的同时,.visibility(this.showFlag) 修饰符会立即生效,导致弹窗内容从渲染树中移除。此时,transition 虽然定义了退场动画,但组件已被隐藏,动画没有机会执行。

解决方案: 需要让退场动画先执行完毕,再触发 controller.close()。你的代码结构已经接近正确,但需要确保状态变更能触发完整的动画流程。

一个更可靠的方法是使用 animateTo 显式控制 showFlag 的状态变化,并确保在动画完成后才关闭控制器。修改你的 cancel() 方法如下:

cancel() {
  // 使用 animateTo 来驱动状态变化,确保动画曲线和时长生效
  animateTo({
    duration: 1000, // 设置退场动画时长
    curve: Curve.EaseOut // 设置退场动画曲线
  }, () => {
    this.showFlag = Visibility.Hidden;
  });
}

同时,确保 transition 中的动画配置与 animateTo 的配置协调(例如时长一致),这样退场动画就能以你设定的速度平滑执行,并在动画结束后通过回调关闭弹窗控制器。

关键点: 直接赋值 this.showFlag = Visibility.Hidden 是瞬时操作,不会等待过渡动画。而 animateTo 将状态变更包裹在动画事务中,使 visibility 的变化过程受动画参数控制,从而让 transition 修饰符定义的动画得以完整播放。

回到顶部