HarmonyOS 鸿蒙Next中转场动画与页面切换效果
HarmonyOS 鸿蒙Next中转场动画与页面切换效果 如何在 ArkUI 中实现页面切换的转场动画?如何自定义组件的出现和消失动画?如何实现共享元素转场?如何处理转场动画中的手势交互?(问题来源项目案例整理:https://github.com/heqiyuan35-creator/HydroQuiz.git)
ArkUI 提供了丰富的动画能力,包括显式动画、属性动画、转场动画等。
animateTo 显式动画:
@State scale: number = 1;
@State opacity: number = 1;
@State rotateAngle: number = 0;
// 基础动画
private playAnimation(): void {
animateTo({
duration: 300,
curve: Curve.EaseOut,
onFinish: () => console.log('动画完成')
}, () => {
this.scale = 1.2;
this.opacity = 0.8;
});
}
// 弹跳动画
private playBounceAnimation(): void {
// 第一阶段:放大
animateTo({ duration: 100, curve: Curve.EaseOut }, () => {
this.scale = 0.9;
});
// 第二阶段:回弹
setTimeout(() => {
animateTo({ duration: 200, curve: Curve.EaseOut }, () => {
this.scale = 1.1;
});
}, 100);
// 第三阶段:恢复
setTimeout(() => {
animateTo({ duration: 150, curve: Curve.EaseInOut }, () => {
this.scale = 1;
});
}, 300);
}
// 循环动画
private playLoopAnimation(): void {
animateTo({
duration: 1000,
curve: Curve.Linear,
iterations: -1, // 无限循环
playMode: PlayMode.Alternate // 往返播放
}, () => {
this.rotateAngle = 360;
});
}
属性动画 .animation():
Column() {
Image($r('app.media.icon'))
.width(100)
.height(100)
.scale({ x: this.scale, y: this.scale })
.opacity(this.opacity)
// 属性动画:当 scale 或 opacity 变化时自动执行动画
.animation({
duration: 300,
curve: Curve.EaseOut
})
}
区别:
- animateTo:主动触发,可以同时改变多个状态
- .animation():被动触发,当绑定的属性变化时自动执行
更多关于HarmonyOS 鸿蒙Next中转场动画与页面切换效果的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next中转场动画与页面切换效果基于ArkUI框架实现。支持共享元素转场、页面转场和组件内转场,通过transition属性配置。常用动画类型包括平移、旋转、缩放和透明度变化。页面切换可通过router模块的push和pop方法触发转场动画。开发者可自定义动画参数如duration和curve,实现平滑过渡效果。
在HarmonyOS Next的ArkUI中,实现页面切换与组件动画主要依赖声明式UI的动画API和转场机制。以下是针对您问题的具体实现方案:
1. 页面切换转场动画
使用Navigation组件时,可通过pageTransition函数为页面配置进入/退出动画:
// 页面级转场
@Entry
@Component
struct PageTransitionExample {
build() {
Navigation() {
PageTransitionPage({ title: 'PageA' })
}
}
}
@Component
struct PageTransitionPage {
build() {
Column() {
// 页面内容
}
.pageTransition({
// 进入动画
slide: SlideEffect.Right,
// 退出动画
opacity: 0.5
})
}
}
2. 组件出现/消失动画
使用transition和animateTo实现组件级动画:
@Component
struct ComponentAnimation {
@State isVisible: boolean = true;
@State opacityVal: number = 1;
build() {
Column() {
if (this.isVisible) {
Text('出现/消失动画')
.transition({ type: TransitionType.Insert, scale: { x: 0, y: 0 } })
.transition({ type: TransitionType.Delete, opacity: 0 })
}
Button('切换显示')
.onClick(() => {
animateTo({
duration: 500,
curve: Curve.EaseInOut
}, () => {
this.isVisible = !this.isVisible;
this.opacityVal = this.isVisible ? 1 : 0;
})
})
}
}
}
3. 共享元素转场
通过sharedTransition实现元素在页面间平滑过渡:
// 页面A
@Component
struct PageA {
build() {
Navigation() {
Column() {
Image($r('app.media.icon'))
.sharedTransition('sharedImage', {
duration: 300,
curve: Curve.Friction
})
.onClick(() => {
router.pushUrl({ url: 'pages/PageB' });
})
}
}
}
}
// 页面B
@Component
struct PageB {
build() {
Column() {
Image($r('app.media.icon'))
.sharedTransition('sharedImage') // 相同ID实现共享
}
}
}
4. 手势交互转场
结合PanGesture和动画API实现手势驱动转场:
@Component
struct GestureTransition {
@State offsetX: number = 0;
@State isExiting: boolean = false;
private panGesture: PanGesture = new PanGesture();
build() {
Column() {
// 可拖拽内容区域
}
.gesture(
this.panGesture
.onActionStart(() => {
// 手势开始
})
.onActionUpdate((event: GestureEvent) => {
// 更新位置
this.offsetX = event.offsetX;
})
.onActionEnd(() => {
// 判断是否触发页面切换
if (Math.abs(this.offsetX) > 100) {
animateTo({
duration: 200,
curve: Curve.EaseOut
}, () => {
this.isExiting = true;
// 执行路由跳转
router.back();
})
}
})
)
.translate({ x: this.offsetX })
}
}
关键要点:
- 转场类型:支持平移、缩放、旋转、透明度等多种效果
- 动画曲线:提供Ease、Spring、Friction等预置曲线,支持自定义贝塞尔曲线
- 性能优化:推荐使用
animateTo的闭包批量更新状态,减少布局计算次数 - 手势协调:通过
gesture修饰符与转场动画结合,实现自然交互体验
这些API共同构成了ArkUI完整的转场动画体系,能够满足从简单页面切换到复杂手势交互动画的各类场景需求。

