1 转场动画定义
如前文所言,转场动画即是组件出现或消失时,对其添加动画的接口。
转场动画是指对将要出现或消失的组件做动画,对始终出现的组件做动画应使用属性动画。转场动画主要为了让开发者从繁重的消失节点管理中解放出来,如果用属性动画做组件转场,开发者需要在动画结束回调中删除组件节点。同时,由于动画结束前已经删除的组件节点可能会重新出现,还需要在结束回调中增加对节点状态的判断。
因此转场动画可以理解为是OpenHarmony动效框架为出现消失场景的动画做的系统侧支持。
具体而言,转场动画可以分为基础转场和高级模板化转场。
注:本文使用的接口为api 10的接口,请确保按照HarmonyOS应用开发环境搭建文档进行正确的环境搭建并且按照上述文档新建的是OpenHarmony项目,才能使用api 10的接口。
2 基础转场
基础转场的接口为.transition,用法为加在需要做出现消失动画的组件上,当组件出现消失时系统侧会对其添加用户定制的动画效果。
例如,有一个按钮,需要点击后出现一张图片,基础的代码为:
ts
@Entry
@Component
struct Index {
@State isImageShow: boolean = false;
build() {
Column() {
Button('Click Me')
.width(100)
.height(30)
.margin(40)
.onClick(() => {
this.isImageShow = !this.isImageShow;
})
// 按钮点击会改变这个bool值,控制图片的出现消失
if (this.isImageShow) {
// 需要在reources/base/media目录下添加一张名为island的图片
Image($r('app.media.island'))
.size({ width: '80%', height: 300 })
}
}
.size({ width: '100%', height: '100%' })
}
}
现在要求图片出现时,是从下往上出现,则这种情况可以通过对图片添加转场动画实现:
ts
Image($r('app.media.island'))
.size({ width: '80%', height: 300 })
// 添加转场效果,出现时从最终位置y轴50vp距离处开始进入,退出时退到y轴50vp距离处,且动画时长为500ms
.transition(TransitionEffect.translate({ y: 50 }).animation({ duration: 500, curve: Curve.Friction }))
效果为:
效果是生效的,为了更好的符合物理世界的效果,可以加上透明度的转场动画:
ts
Image($r('app.media.island'))
.size({ width: '80%', height: 300 })
// 添加转场效果,出现时从最终位置y轴50vp距离处开始进入,退出时退到y轴50vp距离处,且动画时长为500ms
.transition(TransitionEffect.translate({ y: 50 }).animation({ duration: 500, curve: Curve.Friction })
// 添加透明度转场,如果不指定animation,则动画跟随combine的上一个转场的animation,此处动画即为500ms的透明度动画
.combine(TransitionEffect.OPACITY))
效果为:
上述实现是在transition中指定出现消失的动画参数的。在OpenHarmony中,如果控制组件出现消失的flag值是通过动画改变的,那么TransitionEffect也可以不指定.animation,这样会跟随flag的动画属进行动画。如下述代码,效果与上面的效果是一致的:
ts
@Entry
@Component
struct Index {
@State isImageShow: boolean = false;
build() {
Column() {
Button('Click Me')
.width(100)
.height(30)
.margin(40)
.onClick(() => {
// 此处对控制出现消失的isImageShow值加动画
animateTo({
duration: 500,
curve: Curve.Friction
}, () => {
this.isImageShow = !this.isImageShow;
});
})
// 按钮点击会改变这个bool值,控制图片的出现消失
if (this.isImageShow) {
// 需要在reources/base/media目录下添加一张名为island的图片
Image($r('app.media.island'))
.size({ width: '80%', height: 300 })
// 添加转场效果,出现时从最终位置y轴50vp距离处开始进入,退出时退到y轴50vp距离处
// 此时不指定animation,会跟随isImageShow的动画
.transition(TransitionEffect.translate({ y: 50 })
// 添加透明度转场,此时跟随的是isImageShow的动画
.combine(TransitionEffect.OPACITY))
}
}
.size({ width: '100%', height: '100%' })
}
}
3 导航转场
导航转场可以参考官方文档,特性是前一个页面消失,新页面出现。一般来讲导航转场适用于转场后的页面还有跳转逻辑的情形,或者用户可能在新界面停留操作很久的情形(如小红书主页点击卡片,弹出内容页的场景等),Navigation可以合理的管理各页面的跳转逻辑。
使用Navigation及NavRouter等组件即可实现导航效果:
4 模态转场
模态转场可以参考官方文档。包含模态转场和半模态转场等。
特点是前一个页面不消失,后一个页面盖在前一个页面上。适用场景为在应用内弹出一些可简易操作/编辑的页面,如小红书评论区里点开图片,可以通过模态转场bindContentCover弹出图片详情页。
半模态转场bindSheet的效果为: