鸿蒙动画开发05——页面转场动画

如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。

01  概 述

两个页面间发生跳转,一个页面消失,另一个页面出现,这时可以配置各自页面的页面转场参数实现自定义的页面转场效果。

页面转场效果写在pageTransition()函数中,通过PageTransitionEnter和PageTransitionExit指定页面进入和退出的动画效果。

02 接口定义

PageTransitionEnter的接口如下:

PageTransitionEnter({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number})

PageTransitionExit的接口如下:

PageTransitionExit({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number})

其中,RouteType的取值有三种:

    • Pop:重定向指定页面。从PageB回退到之前的页面PageA。对于PageB,指定RouteType为None或者Pop的PageTransitionExit组件样式生效,对于PageA,指定RouteType为None或者Pop的PageTransitionEnter组件样式生效。

    • Push:跳转到下一页面。PageA跳转到下一个新的界面PageB。对于PageA,指定RouteType为None或者Push的PageTransitionExit组件样式生效,对于PageB,指定RouteType为None或者Push的PageTransitionEnter组件样式生效。

    • None:页面未重定向。如Push和Pop描述中RouteType为None的情形,即页面进场时PageTransitionEnter的转场效果生效;退场时PageTransitionExit的转场效果生效。

上述接口定义了PageTransitionEnter和PageTransitionExit组件,可通过slide、translate、scale、opacity属性定义不同的页面转场效果。

对于PageTransitionEnter而言,这些效果表示入场时起点值,对于PageTransitionExit而言,这些效果表示退场的终点值,这一点与组件转场transition配置方法类似。

此外,PageTransitionEnter提供了onEnter接口进行自定义页面入场动画的回调,PageTransitionExit提供了onExit接口进行自定义页面退场动画的回调。

    上述接口中的参数type,表示路由生效的类型,这一点开发者容易混淆其含义。

    页面转场的两个页面,必定有一个页面退出,一个页面进入。如果通过router.pushUrl操作从页面A跳转到页面B,则页面A退出,做页面退场动画,页面B进入,做页面入场动画。

    如果通过router.back操作从页面B返回到页面A,则页面B退出,做页面退场动画,页面A进入,做页面入场动画。即页面的PageTransitionEnter既可能是由于新增页面(push,入栈)引起的新页面的入场动画,也可能是由于页面返回(back,或pop,出栈)引起的页面栈中老页面的入场动画,为了能区分这两种形式的入场动画,提供了type参数,这样开发者能完全定义所有类型的页面转场效果。

👉🏻 routeType为None

type为RouteType.None表示对页面栈的push、pop操作均生效,type的默认值为RouteType.None。

// page ApageTransition() {  // 定义页面进入时的效果,从左侧滑入,时长为1200ms,无论页面栈发生push还是pop操作均可生效  PageTransitionEnter({ type: RouteType.None, duration: 1200 })    .slide(SlideEffect.Left)  // 定义页面退出时的效果,向左侧滑出,时长为1000ms,无论页面栈发生push还是pop操作均可生效  PageTransitionExit({ type: RouteType.None, duration: 1000 })    .slide(SlideEffect.Left)}
// page BpageTransition() {  // 定义页面进入时的效果,从右侧滑入,时长为1000ms,无论页面栈发生push还是pop操作均可生效  PageTransitionEnter({ type: RouteType.None, duration: 1000 })    .slide(SlideEffect.Right)  // 定义页面退出时的效果,向右侧滑出,时长为1200ms,无论页面栈发生push还是pop操作均可生效  PageTransitionExit({ type: RouteType.None, duration: 1200 })    .slide(SlideEffect.Right)}

假设页面栈为标准实例模式,即页面栈中允许存在重复的页面。可能会有4种场景,对应的页面转场效果如下表。

图片

如果希望pushUrl进入的页面总是从右侧滑入,back时退出的页面总是从右侧滑出,则上表中的第3、4种情况不满足要求,那么需要完整的定义4个页面转场效果。

👉🏻 routeType为Push、Pop

type为RouteType.Push表示仅对页面栈的push操作生效,type为RouteType.Pop表示仅对页面栈的pop操作生效。

// page ApageTransition() {  // 定义页面进入时的效果,从右侧滑入,时长为1200ms,页面栈发生push操作时该效果才生效  PageTransitionEnter({ type: RouteType.Push, duration: 1200 })    .slide(SlideEffect.Right)  // 定义页面进入时的效果,从左侧滑入,时长为1200ms,页面栈发生pop操作时该效果才生效  PageTransitionEnter({ type: RouteType.Pop, duration: 1200 })    .slide(SlideEffect.Left)  // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效  PageTransitionExit({ type: RouteType.Push, duration: 1000 })    .slide(SlideEffect.Left)  // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效  PageTransitionExit({ type: RouteType.Pop, duration: 1000 })    .slide(SlideEffect.Right)}​​​​​​​
// page BpageTransition() {  // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效  PageTransitionEnter({ type: RouteType.Push, duration: 1000 })    .slide(SlideEffect.Right)  // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效  PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })    .slide(SlideEffect.Left)  // 定义页面退出时的效果,向左侧滑出,时长为1200ms,页面栈发生push操作时该效果才生效  PageTransitionExit({ type: RouteType.Push, duration: 1200 })    .slide(SlideEffect.Left)  // 定义页面退出时的效果,向右侧滑出,时长为1200ms,页面栈发生pop操作时该效果才生效  PageTransitionExit({ type: RouteType.Pop, duration: 1200 })    .slide(SlideEffect.Right)}

以上代码则完整的定义了所有可能的页面转场样式。假设页面栈为标准实例模式,即页面栈中允许存在重复的页面。可能会有4种场景,对应的页面转场效果如下表。

图片

1. 由于每个页面的页面转场样式都可由开发者独立配置,而页面转场涉及到两个页面,开发者应考虑两个页面的页面转场效果的衔接,如时长尽量保持一致。

2. 如果没有定义匹配的页面转场样式,则该页面使用系统默认的页面转场样式。

👉🏻 禁用某页面的页面转场

通过设置页面转场的时长为0,可使该页面无页面转场动画。代码如下:​​​​​​​

pageTransition() {  PageTransitionEnter({ type: RouteType.None, duration: 0 })  PageTransitionExit({ type: RouteType.None, duration: 0 })}

页面转场动画示例​​​​​​​

// PageTransitionSrc1import router from '@ohos.router';@Entry@Componentstruct PageTransitionSrc1 {  build() {    Column() {      Image($r('app.media.mountain'))        .width('90%')        .height('80%')        .objectFit(ImageFit.Fill)        .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成        .margin(30)      Row({ space: 10 }) {        Button("pushUrl")          .onClick(() => {            // 路由到下一个页面,push操作            router.pushUrl({ url: 'pages/myTest/pageTransitionDst1' });          })        Button("back")          .onClick(() => {            // 返回到上一页面,相当于pop操作            router.back();          })      }.justifyContent(FlexAlign.Center)    }    .width("100%").height("100%")    .alignItems(HorizontalAlign.Center)  }  pageTransition() {    // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效    PageTransitionEnter({ type: RouteType.Push, duration: 1000 })      .slide(SlideEffect.Right)    // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效    PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })      .slide(SlideEffect.Left)    // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效    PageTransitionExit({ type: RouteType.Push, duration: 1000 })      .slide(SlideEffect.Left)    // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效    PageTransitionExit({ type: RouteType.Pop, duration: 1000 })      .slide(SlideEffect.Right)  }}​​​​​
// PageTransitionDst1import router from '@ohos.router';@Entry@Componentstruct PageTransitionDst1 {  build() {    Column() {      Image($r('app.media.forest'))        .width('90%')        .height('80%')        .objectFit(ImageFit.Fill)        .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成        .margin(30)
      Row({ space: 10 }) {        Button("pushUrl")          .onClick(() => {            // 路由到下一页面,push操作            router.pushUrl({ url: 'pages/myTest/pageTransitionSrc1' });          })        Button("back")          .onClick(() => {            // 返回到上一页面,相当于pop操作            router.back();          })      }.justifyContent(FlexAlign.Center)    }    .width("100%").height("100%")    .alignItems(HorizontalAlign.Center)  }
  pageTransition() {    // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效    PageTransitionEnter({ type: RouteType.Push, duration: 1000 })      .slide(SlideEffect.Right)    // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效    PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })      .slide(SlideEffect.Left)    // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效    PageTransitionExit({ type: RouteType.Push, duration: 1000 })      .slide(SlideEffect.Left)    // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效    PageTransitionExit({ type: RouteType.Pop, duration: 1000 })      .slide(SlideEffect.Right)  }}

图片

下面介绍使用了type为None的页面转场动画示例。​​​​​​​

// PageTransitionSrc2import router from '@ohos.router';@Entry@Componentstruct PageTransitionSrc2 {  build() {    Column() {      Image($r('app.media.mountain'))        .width('90%')        .height('80%')        .objectFit(ImageFit.Fill)        .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成        .margin(30)      Row({ space: 10 }) {        Button("pushUrl")          .onClick(() => {            // 路由到下一页面,push操作            router.pushUrl({ url: 'pages/myTest/pageTransitionDst2' });          })        Button("back")          .onClick(() => {            // 返回到上一页面,相当于pop操作            router.back();          })      }.justifyContent(FlexAlign.Center)    }    .width("100%").height("100%")    .alignItems(HorizontalAlign.Center)  }  pageTransition() {    // 定义页面进入时的效果,从左侧滑入,时长为1000ms,无论页面栈发生push还是pop操作均可生效    PageTransitionEnter({ duration: 1000 })      .slide(SlideEffect.Left)    // 定义页面退出时的效果,相对于正常页面位置x方向平移100vp,y方向平移100vp,透明度变为0,时长为1200ms,无论页面栈发生push还是pop操作均可生效    PageTransitionExit({ duration: 1200 })      .translate({ x: 100.0, y: 100.0 })      .opacity(0)  }}​​​​​​​
// PageTransitionDst2import router from '@ohos.router';@Entry@Componentstruct PageTransitionDst2 {  build() {    Column() {      Image($r('app.media.forest'))        .width('90%')        .height('80%')        .objectFit(ImageFit.Fill)        .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成        .margin(30)      Row({ space: 10 }) {        Button("pushUrl")          .onClick(() => {            // 路由到下一页面,push操作            router.pushUrl({ url: 'pages/myTest/pageTransitionSrc2' });          })        Button("back")          .onClick(() => {            // 返回到上一页面,相当于pop操作            router.back();          })      }.justifyContent(FlexAlign.Center)    }    .width("100%").height("100%")    .alignItems(HorizontalAlign.Center)  }  pageTransition() {    // 定义页面进入时的效果,从左侧滑入,时长为1200ms,无论页面栈发生push还是pop操作均可生效    PageTransitionEnter({ duration: 1200 })      .slide(SlideEffect.Left)    // 定义页面退出时的效果,相对于正常页面位置x方向平移100vp,y方向平移100vp,透明度变为0,时长为1000ms,无论页面栈发生push还是pop操作均可生效    PageTransitionExit({ duration: 1000 })      .translate({ x: 100.0, y: 100.0 })      .opacity(0)  }}

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值