codecamp

页面转场动画

两个页面间发生跳转,一个页面消失,另一个页面出现,这时可以配置各自页面的页面转场参数实现自定义的页面转场效果。页面转场效果写在pageTransition函数中,通过PageTransitionEnter和PageTransitionExit指定页面进入和退出的动画效果。

PageTransitionEnter的接口为:

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

PageTransitionExit的接口为:

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

上述接口定义了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参数,这样开发者能完全定义所有类型的页面转场效果。

type配置为RouteType.None

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

  1. // page A
  2. pageTransition() {
  3. // 定义页面进入时的效果,从左侧滑入,时长为1200ms,无论页面栈发生push还是pop操作均可生效
  4. PageTransitionEnter({ type: RouteType.None, duration: 1200 })
  5. .slide(SlideEffect.Left)
  6. // 定义页面退出时的效果,向左侧滑出,时长为1000ms,无论页面栈发生push还是pop操作均可生效
  7. PageTransitionExit({ type: RouteType.None, duration: 1000 })
  8. .slide(SlideEffect.Left)
  9. }
  1. // page B
  2. pageTransition() {
  3. // 定义页面进入时的效果,从右侧滑入,时长为1000ms,无论页面栈发生push还是pop操作均可生效
  4. PageTransitionEnter({ type: RouteType.None, duration: 1000 })
  5. .slide(SlideEffect.Right)
  6. // 定义页面退出时的效果,向右侧滑出,时长为1200ms,无论页面栈发生push还是pop操作均可生效
  7. PageTransitionExit({ type: RouteType.None, duration: 1200 })
  8. .slide(SlideEffect.Right)
  9. }

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

路由操作

页面A转场效果

页面B转场效果

router.pushUrl,从页面A跳转到新增的页面B

页面退出,PageTransitionExit生效,向左侧滑出屏幕

页面进入,PageTransitionEnter生效,从右侧滑入屏幕

router.back,从页面B返回到页面A

页面进入,PageTransitionEnter生效,从左侧滑入屏幕

页面退出,PageTransitionExit生效,向右侧滑出屏幕

router.pushUrl,从页面B跳转到新增的页面A

页面进入,PageTransitionEnter生效,从左侧滑入屏幕

页面退出,PageTransitionExit生效,向右侧滑出屏幕

router.back,从页面A返回到页面B

页面退出,PageTransitionExit生效,向左侧滑出屏幕

页面进入,PageTransitionEnter生效,从右侧滑入屏幕

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

type配置为RouteType.Push或RouteType.Pop

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

  1. // page A
  2. pageTransition() {
  3. // 定义页面进入时的效果,从右侧滑入,时长为1200ms,页面栈发生push操作时该效果才生效
  4. PageTransitionEnter({ type: RouteType.Push, duration: 1200 })
  5. .slide(SlideEffect.Right)
  6. // 定义页面进入时的效果,从左侧滑入,时长为1200ms,页面栈发生pop操作时该效果才生效
  7. PageTransitionEnter({ type: RouteType.Pop, duration: 1200 })
  8. .slide(SlideEffect.Left)
  9. // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效
  10. PageTransitionExit({ type: RouteType.Push, duration: 1000 })
  11. .slide(SlideEffect.Left)
  12. // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效
  13. PageTransitionExit({ type: RouteType.Pop, duration: 1000 })
  14. .slide(SlideEffect.Right)
  15. }
  1. // page B
  2. pageTransition() {
  3. // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效
  4. PageTransitionEnter({ type: RouteType.Push, duration: 1000 })
  5. .slide(SlideEffect.Right)
  6. // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效
  7. PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })
  8. .slide(SlideEffect.Left)
  9. // 定义页面退出时的效果,向左侧滑出,时长为1200ms,页面栈发生push操作时该效果才生效
  10. PageTransitionExit({ type: RouteType.Push, duration: 1200 })
  11. .slide(SlideEffect.Left)
  12. // 定义页面退出时的效果,向右侧滑出,时长为1200ms,页面栈发生pop操作时该效果才生效
  13. PageTransitionExit({ type: RouteType.Pop, duration: 1200 })
  14. .slide(SlideEffect.Right)
  15. }

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

路由操作

页面A转场效果

页面B转场效果

router.pushUrl,从页面A跳转到新增的页面B

页面退出,PageTransitionExit且type为RouteType.Push的转场样式生效,向左侧滑出屏幕

页面进入,PageTransitionEnter且type为RouteType.Push的转场样式生效,从右侧滑入屏幕

router.back,从页面B返回到页面A

页面进入,PageTransitionEnter且type为RouteType.Pop的转场样式生效,从左侧滑入屏幕

页面退出,PageTransitionExit且type为RouteType.Pop的转场样式生效,向右侧滑出屏幕

router.pushUrl,从页面B跳转到新增的页面A

页面进入,PageTransitionEnter且type为RouteType.Push的转场样式生效,从右侧滑入屏幕

页面退出,PageTransitionExit且type为RouteType.Push的转场样式生效,向左侧滑出屏幕

router.back,从页面A返回到页面B

页面退出,PageTransitionExit且type为RouteType.Pop的转场样式生效,向右侧滑出屏幕

页面进入,PageTransitionEnter且type为RouteType.Pop的转场样式生效,从左侧滑入屏幕

说明

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

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

禁用某页面的页面转场

  1. pageTransition() {
  2. PageTransitionEnter({ type: RouteType.None, duration: 0 })
  3. PageTransitionExit({ type: RouteType.None, duration: 0 })
  4. }

通过设置页面转场的时长为0,可使该页面无页面转场动画。

场景示例

下面介绍定义了所有的四种页面转场样式的页面转场动画示例。

  1. // PageTransitionSrc1
  2. import router from '@ohos.router';
  3. @Entry
  4. @Component
  5. struct PageTransitionSrc1 {
  6. build() {
  7. Column() {
  8. Image($r('app.media.mountain'))
  9. .width('90%')
  10. .height('80%')
  11. .objectFit(ImageFit.Fill)
  12. .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一个页面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionDst1' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一页面,相当于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效
  32. PageTransitionEnter({ type: RouteType.Push, duration: 1000 })
  33. .slide(SlideEffect.Right)
  34. // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效
  35. PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })
  36. .slide(SlideEffect.Left)
  37. // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效
  38. PageTransitionExit({ type: RouteType.Push, duration: 1000 })
  39. .slide(SlideEffect.Left)
  40. // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效
  41. PageTransitionExit({ type: RouteType.Pop, duration: 1000 })
  42. .slide(SlideEffect.Right)
  43. }
  44. }

  1. // PageTransitionDst1
  2. import router from '@ohos.router';
  3. @Entry
  4. @Component
  5. struct PageTransitionDst1 {
  6. build() {
  7. Column() {
  8. Image($r('app.media.forest'))
  9. .width('90%')
  10. .height('80%')
  11. .objectFit(ImageFit.Fill)
  12. .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一页面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionSrc1' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一页面,相当于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定义页面进入时的效果,从右侧滑入,时长为1000ms,页面栈发生push操作时该效果才生效
  32. PageTransitionEnter({ type: RouteType.Push, duration: 1000 })
  33. .slide(SlideEffect.Right)
  34. // 定义页面进入时的效果,从左侧滑入,时长为1000ms,页面栈发生pop操作时该效果才生效
  35. PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })
  36. .slide(SlideEffect.Left)
  37. // 定义页面退出时的效果,向左侧滑出,时长为1000ms,页面栈发生push操作时该效果才生效
  38. PageTransitionExit({ type: RouteType.Push, duration: 1000 })
  39. .slide(SlideEffect.Left)
  40. // 定义页面退出时的效果,向右侧滑出,时长为1000ms,页面栈发生pop操作时该效果才生效
  41. PageTransitionExit({ type: RouteType.Pop, duration: 1000 })
  42. .slide(SlideEffect.Right)
  43. }
  44. }

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

  1. // PageTransitionSrc2
  2. import router from '@ohos.router';
  3. @Entry
  4. @Component
  5. struct PageTransitionSrc2 {
  6. build() {
  7. Column() {
  8. Image($r('app.media.mountain'))
  9. .width('90%')
  10. .height('80%')
  11. .objectFit(ImageFit.Fill)
  12. .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一页面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionDst2' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一页面,相当于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定义页面进入时的效果,从左侧滑入,时长为1000ms,无论页面栈发生push还是pop操作均可生效
  32. PageTransitionEnter({ duration: 1000 })
  33. .slide(SlideEffect.Left)
  34. // 定义页面退出时的效果,相对于正常页面位置x方向平移100vp,y方向平移100vp,透明度变为0,时长为1200ms,无论页面栈发生push还是pop操作均可生效
  35. PageTransitionExit({ duration: 1200 })
  36. .translate({ x: 100.0, y: 100.0 })
  37. .opacity(0)
  38. }
  39. }
  1. // PageTransitionDst2
  2. import router from '@ohos.router';
  3. @Entry
  4. @Component
  5. struct PageTransitionDst2 {
  6. build() {
  7. Column() {
  8. Image($r('app.media.forest'))
  9. .width('90%')
  10. .height('80%')
  11. .objectFit(ImageFit.Fill)
  12. .syncLoad(true) // 同步加载图片,使页面出现时图片已经加载完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一页面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionSrc2' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一页面,相当于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定义页面进入时的效果,从左侧滑入,时长为1200ms,无论页面栈发生push还是pop操作均可生效
  32. PageTransitionEnter({ duration: 1200 })
  33. .slide(SlideEffect.Left)
  34. // 定义页面退出时的效果,相对于正常页面位置x方向平移100vp,y方向平移100vp,透明度变为0,时长为1000ms,无论页面栈发生push还是pop操作均可生效
  35. PageTransitionExit({ duration: 1000 })
  36. .translate({ x: 100.0, y: 100.0 })
  37. .opacity(0)
  38. }
  39. }

放大缩小视图
触屏事件
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录
HAR

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }