【HarmonyOS开发小实践】ArkUI 转场动画组件出现、消失与页面切换的过渡
ArkUI 转场动画:组件出现、消失与页面切换的过渡
转场是"出现"和"消失"的动画
属性动画管的是"值怎么变",转场动画管的是"组件怎么出现、怎么消失"。元素插入界面、删除界面、页面之间切换,都需要转场来避免生硬的瞬间跳变。
ArkUI 的转场分两类:组件转场(组件出现和消失)和页面转场(页面之间切换)。
组件转场:transition
transition 定义组件插入和移除时的过渡效果:
@Entry
@Component
struct TransitionDemo {
@State show: boolean = false;
build() {
Column({ space: 20 }) {
Button('显示/隐藏')
.onClick(() => {
this.show = !this.show;
})
// 条件渲染的组件,出现和消失带转场
if (this.show) {
Text('我出现了')
.fontSize(24)
.transition(
TransitionEffect.OPACITY // 淡入淡出
.animation({ duration: 500, curve: Curve.EaseInOut })
)
}
}
}
}
TransitionEffect 提供多种效果,可以组合:
| 效果 | 作用 |
|---|---|
TransitionEffect.OPACITY | 淡入淡出 |
TransitionEffect.SLIDE | 滑动进入退出 |
TransitionEffect.translate({}) | 平移(指定方向) |
TransitionEffect.scale({}) | 缩放 |
TransitionEffect.rotate({}) | 旋转 |
.combine() | 组合多种效果 |
.asymmetric() | 进入和退出用不同效果 |
组合转场效果
多个效果用 .combine() 串联:
if (this.show) {
Text('复合转场')
.transition(
TransitionEffect.OPACITY
.combine(TransitionEffect.translate({ x: 200 })) // 淡入 + 从右滑入
.animation({ duration: 300, curve: Curve.EaseInOut })
)
}
这个组件出现时"淡入 + 从右侧滑入",消失时反向。
进入和退出用不同效果
asymmetric 让进入动画和退出动画不一样:
if (this.show) {
Text('非对称转场')
.transition(
TransitionEffect.OPACITY
.asymmetric(
// 进入:淡入 + 从右滑入
TransitionEffect.OPACITY.combine(TransitionEffect.translate({ x: 200 })),
// 退出:淡出 + 向左滑出
TransitionEffect.OPACITY.combine(TransitionEffect.translate({ x: -200 }))
)
.animation({ duration: 300 })
)
}
进入从右滑入,退出向左滑出,模拟"进栈"和"出栈"的方向感。
页面转场:Navigation 的 transition
页面之间切换也有转场。Navigation 的 NavDestination 支持页面转场:
@Component
struct DetailPage {
build() {
NavDestination() {
Text('详情页')
}
// 页面转场:默认滑动 + 淡入
.transition(
TransitionEffect.translate({ x: '100%' })
.combine(TransitionEffect.OPACITY)
)
}
}
页面切换的默认转场是水平滑动 + 淡入淡出。可以自定义,但要注意:页面级的转场过重会影响导航流畅度。
弹窗式提示的转场
一个常见的"加载成功提示":淡入出现,停留,淡出消失。
@Entry
@Component
struct ToastDemo {
@State showToast: boolean = false;
@State toastMsg: string = '';
build() {
Stack({ alignContent: Alignment.Center }) {
Column({ space: 20 }) {
Button('显示提示')
.onClick(() => {
this.toastMsg = '操作成功';
this.showToast = true;
// 2 秒后自动隐藏
setTimeout(() => {
this.showToast = false;
}, 2000);
})
}
// 提示浮层:淡入淡出
if (this.showToast) {
Text(this.toastMsg)
.fontColor(Color.White)
.backgroundColor('#80000000')
.padding(16)
.borderRadius(8)
.transition(
TransitionEffect.OPACITY
.combine(TransitionEffect.scale({ x: 0.8, y: 0.8 })) // 淡入 + 缩放
.animation({ duration: 200 })
)
}
}
}
}
这个提示出现时淡入 + 从 0.8 倍放大到 1 倍,消失时反向,配合 200ms 的短时长,轻量不突兀。
转场动画的小经验
-
转场要短。组件出现消失的转场 200-300ms 合适,页面转场可以稍长到 300-400ms。转场太慢会让用户感觉操作延迟。
-
进入退出方向要有逻辑。列表项新增从顶部滑入、删除向左侧滑出,符合用户的直觉预期。方向乱来会让人困惑。
-
条件渲染才触发转场。
if条件渲染的组件,条件从 false 到 true 触发进入转场,true 到 false 触发退出转场。如果用visibility隐藏,不会触发退出转场,这点要区分。 -
别滥用转场。不是每个元素出现都要转场,重要提示、弹窗、页面切换加转场能提升体验,普通列表渲染加转场反而累赘。
-
转场和状态要配合。转场动画触发的前提是状态变化(
if条件),确保@State切换正确,转场才会按预期执行。
更多推荐

所有评论(0)