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
由于通过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 变为 Hidden 且 transitionIn 为 false(表示退场动画结束时)才关闭弹窗控制器,这本身是正确的逻辑。
但弹窗“立即收回”的原因是:在 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 修饰符定义的动画得以完整播放。


