HarmonyOS 鸿蒙Next中如何自定义弹窗的弹出动画和关闭动画

HarmonyOS 鸿蒙Next中如何自定义弹窗的弹出动画和关闭动画 可以通过给弹窗设置组件转场动画transition来实现,参考代码如下:

@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController;
  @State showFlag: Visibility = Visibility.Visible;

  build() {
    Column() {
      Button('Close the pop-up window')
    }
    .width('100%')
    .height(400)
    .backgroundColor(Color.Gray)
    .onClick(() => {
      this.cancel();
    })
    .visibility(this.showFlag)
    //Set the animation event to 200ms in the core code, and set the starting point and ending point for component transitions to 100vp below the screen
    .transition(TransitionEffect.OPACITY.animation({ duration: 200 }).combine(TransitionEffect.translate({ y: 100 })))
  }

  //When deleting, it should be noted that if the pop-up window is closed directly, there will be no transition effect. You can first use explicit and implicit control,
  //Set the pop-up window to be hidden, and the downward exit animation will take effect. Then set a delay to close the pop-up window.
  cancel() {
    this.showFlag = Visibility.Hidden;
    setTimeout(() => {
      this.controller.close();
    }, 200)
  }
}

@Entry
@Component
struct CustomDialogUser {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample(),
    autoCancel: false,
    customStyle: true
  })

  build() {
    Column() {
      Button('click me')
        .onClick(() => {
          this.dialogController.open();
        })
    }
    .width('100%')
    .height('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next中如何自定义弹窗的弹出动画和关闭动画的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

感谢楼主分享,嘿连续搞到两个需要的功能

更多关于HarmonyOS 鸿蒙Next中如何自定义弹窗的弹出动画和关闭动画的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,自定义弹窗动画可通过CustomDialogController实现。使用CustomDialog组件,在CustomDialogControlleronAboutToAppearonAboutToDisappear生命周期中,通过animateTo方法定义弹出和关闭动画。动画属性可设置透明度、缩放、位移等,例如opacityscaletranslate

在HarmonyOS Next中,自定义弹窗的弹出和关闭动画,核心是使用组件的.transition方法,并配合显隐状态(Visibility)来控制动画的触发时机。你提供的代码示例是正确的实现路径。

关键点解析:

  1. 动画定义:通过.transition(TransitionEffect)为组件(这里是弹窗的根容器Column)设置转场效果。你可以使用内置效果(如OPACITYSCALE)或通过TransitionEffect.translate.rotate等进行自定义组合,并使用.animation方法配置动画参数(时长、曲线等)。

    .transition(TransitionEffect.OPACITY.animation({ duration: 200 }).combine(TransitionEffect.translate({ y: 100 })))
    
  2. 动画触发:转场动画会在组件的显隐状态(Visibility)发生变化时自动播放。因此,需要将@State变量与.visibility修饰符绑定。

    @State showFlag: Visibility = Visibility.Visible;
    ...
    .visibility(this.showFlag)
    
  3. 关闭动画的实现:这是关键。直接调用controller.close()会立即销毁弹窗组件,动画无法播放。正确做法是:

    • 先将绑定的显隐状态设置为Visibility.Hidden,这会触发组件播放“退出”动画(即你定义的transition动画的逆过程)。
    • 使用setTimeout延迟一段时间(大于等于动画时长),在动画播放完毕后,再调用controller.close()来真正关闭并销毁弹窗。
    cancel() {
      this.showFlag = Visibility.Hidden; // 触发关闭动画
      setTimeout(() => {
        this.controller.close(); // 动画结束后关闭弹窗
      }, 200) // 延迟时间需≥动画时长
    }
    
  4. 弹出动画:当CustomDialogController执行open()方法时,弹窗组件被创建并初始化为Visibility.Visible状态,此时会自动播放“进入”动画。

总结:你的代码清晰地展示了如何利用transitionVisibility状态分离动画逻辑与弹窗生命周期,从而实现对自定义弹窗进出动画的完整控制。这种方法灵活且符合ArkUI的声明式动画范式。

回到顶部