頁(yè)面轉(zhuǎn)場(chǎng)動(dòng)畫

2024-02-07 12:45 更新

兩個(gè)頁(yè)面間發(fā)生跳轉(zhuǎn),一個(gè)頁(yè)面消失,另一個(gè)頁(yè)面出現(xiàn),這時(shí)可以配置各自頁(yè)面的頁(yè)面轉(zhuǎn)場(chǎng)參數(shù)實(shí)現(xiàn)自定義的頁(yè)面轉(zhuǎn)場(chǎng)效果。頁(yè)面轉(zhuǎn)場(chǎng)效果寫在pageTransition函數(shù)中,通過PageTransitionEnter和PageTransitionExit指定頁(yè)面進(jìn)入和退出的動(dòng)畫效果。

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屬性定義不同的頁(yè)面轉(zhuǎn)場(chǎng)效果。對(duì)于PageTransitionEnter而言,這些效果表示入場(chǎng)時(shí)起點(diǎn)值,對(duì)于PageTransitionExit而言,這些效果表示退場(chǎng)的終點(diǎn)值,這一點(diǎn)與組件轉(zhuǎn)場(chǎng)transition配置方法類似。此外,PageTransitionEnter提供了onEnter接口進(jìn)行自定義頁(yè)面入場(chǎng)動(dòng)畫的回調(diào),PageTransitionExit提供了onExit接口進(jìn)行自定義頁(yè)面退場(chǎng)動(dòng)畫的回調(diào)。

上述接口中的參數(shù)type,表示路由生效的類型,這一點(diǎn)開發(fā)者容易混淆其含義。頁(yè)面轉(zhuǎn)場(chǎng)的兩個(gè)頁(yè)面,必定有一個(gè)頁(yè)面退出,一個(gè)頁(yè)面進(jìn)入。如果通過router.pushUrl操作從頁(yè)面A跳轉(zhuǎn)到頁(yè)面B,則頁(yè)面A退出,做頁(yè)面退場(chǎng)動(dòng)畫,頁(yè)面B進(jìn)入,做頁(yè)面入場(chǎng)動(dòng)畫。如果通過router.back操作從頁(yè)面B返回到頁(yè)面A,則頁(yè)面B退出,做頁(yè)面退場(chǎng)動(dòng)畫,頁(yè)面A進(jìn)入,做頁(yè)面入場(chǎng)動(dòng)畫。即頁(yè)面的PageTransitionEnter既可能是由于新增頁(yè)面(push,入棧)引起的新頁(yè)面的入場(chǎng)動(dòng)畫,也可能是由于頁(yè)面返回(back,或pop,出棧)引起的頁(yè)面棧中老頁(yè)面的入場(chǎng)動(dòng)畫,為了能區(qū)分這兩種形式的入場(chǎng)動(dòng)畫,提供了type參數(shù),這樣開發(fā)者能完全定義所有類型的頁(yè)面轉(zhuǎn)場(chǎng)效果。

type配置為RouteType.None

type為RouteType.None表示對(duì)頁(yè)面棧的push、pop操作均生效,type的默認(rèn)值為RouteType.None。

  1. // page A
  2. pageTransition() {
  3. // 定義頁(yè)面進(jìn)入時(shí)的效果,從左側(cè)滑入,時(shí)長(zhǎng)為1200ms,無(wú)論頁(yè)面棧發(fā)生push還是pop操作均可生效
  4. PageTransitionEnter({ type: RouteType.None, duration: 1200 })
  5. .slide(SlideEffect.Left)
  6. // 定義頁(yè)面退出時(shí)的效果,向左側(cè)滑出,時(shí)長(zhǎng)為1000ms,無(wú)論頁(yè)面棧發(fā)生push還是pop操作均可生效
  7. PageTransitionExit({ type: RouteType.None, duration: 1000 })
  8. .slide(SlideEffect.Left)
  9. }
  1. // page B
  2. pageTransition() {
  3. // 定義頁(yè)面進(jìn)入時(shí)的效果,從右側(cè)滑入,時(shí)長(zhǎng)為1000ms,無(wú)論頁(yè)面棧發(fā)生push還是pop操作均可生效
  4. PageTransitionEnter({ type: RouteType.None, duration: 1000 })
  5. .slide(SlideEffect.Right)
  6. // 定義頁(yè)面退出時(shí)的效果,向右側(cè)滑出,時(shí)長(zhǎng)為1200ms,無(wú)論頁(yè)面棧發(fā)生push還是pop操作均可生效
  7. PageTransitionExit({ type: RouteType.None, duration: 1200 })
  8. .slide(SlideEffect.Right)
  9. }

假設(shè)頁(yè)面棧為標(biāo)準(zhǔn)實(shí)例模式,即頁(yè)面棧中允許存在重復(fù)的頁(yè)面??赡軙?huì)有4種場(chǎng)景,對(duì)應(yīng)的頁(yè)面轉(zhuǎn)場(chǎng)效果如下表。

路由操作

頁(yè)面A轉(zhuǎn)場(chǎng)效果

頁(yè)面B轉(zhuǎn)場(chǎng)效果

router.pushUrl,從頁(yè)面A跳轉(zhuǎn)到新增的頁(yè)面B

頁(yè)面退出,PageTransitionExit生效,向左側(cè)滑出屏幕

頁(yè)面進(jìn)入,PageTransitionEnter生效,從右側(cè)滑入屏幕

router.back,從頁(yè)面B返回到頁(yè)面A

頁(yè)面進(jìn)入,PageTransitionEnter生效,從左側(cè)滑入屏幕

頁(yè)面退出,PageTransitionExit生效,向右側(cè)滑出屏幕

router.pushUrl,從頁(yè)面B跳轉(zhuǎn)到新增的頁(yè)面A

頁(yè)面進(jìn)入,PageTransitionEnter生效,從左側(cè)滑入屏幕

頁(yè)面退出,PageTransitionExit生效,向右側(cè)滑出屏幕

router.back,從頁(yè)面A返回到頁(yè)面B

頁(yè)面退出,PageTransitionExit生效,向左側(cè)滑出屏幕

頁(yè)面進(jìn)入,PageTransitionEnter生效,從右側(cè)滑入屏幕

如果希望pushUrl進(jìn)入的頁(yè)面總是從右側(cè)滑入,back時(shí)退出的頁(yè)面總是從右側(cè)滑出,則上表中的第3、4種情況不滿足要求,那么需要完整的定義4個(gè)頁(yè)面轉(zhuǎn)場(chǎng)效果。

type配置為RouteType.Push或RouteType.Pop

type為RouteType.Push表示僅對(duì)頁(yè)面棧的push操作生效,type為RouteType.Pop表示僅對(duì)頁(yè)面棧的pop操作生效。

  1. // page A
  2. pageTransition() {
  3. // 定義頁(yè)面進(jìn)入時(shí)的效果,從右側(cè)滑入,時(shí)長(zhǎng)為1200ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  4. PageTransitionEnter({ type: RouteType.Push, duration: 1200 })
  5. .slide(SlideEffect.Right)
  6. // 定義頁(yè)面進(jìn)入時(shí)的效果,從左側(cè)滑入,時(shí)長(zhǎng)為1200ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  7. PageTransitionEnter({ type: RouteType.Pop, duration: 1200 })
  8. .slide(SlideEffect.Left)
  9. // 定義頁(yè)面退出時(shí)的效果,向左側(cè)滑出,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  10. PageTransitionExit({ type: RouteType.Push, duration: 1000 })
  11. .slide(SlideEffect.Left)
  12. // 定義頁(yè)面退出時(shí)的效果,向右側(cè)滑出,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  13. PageTransitionExit({ type: RouteType.Pop, duration: 1000 })
  14. .slide(SlideEffect.Right)
  15. }
  1. // page B
  2. pageTransition() {
  3. // 定義頁(yè)面進(jìn)入時(shí)的效果,從右側(cè)滑入,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  4. PageTransitionEnter({ type: RouteType.Push, duration: 1000 })
  5. .slide(SlideEffect.Right)
  6. // 定義頁(yè)面進(jìn)入時(shí)的效果,從左側(cè)滑入,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  7. PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })
  8. .slide(SlideEffect.Left)
  9. // 定義頁(yè)面退出時(shí)的效果,向左側(cè)滑出,時(shí)長(zhǎng)為1200ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  10. PageTransitionExit({ type: RouteType.Push, duration: 1200 })
  11. .slide(SlideEffect.Left)
  12. // 定義頁(yè)面退出時(shí)的效果,向右側(cè)滑出,時(shí)長(zhǎng)為1200ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  13. PageTransitionExit({ type: RouteType.Pop, duration: 1200 })
  14. .slide(SlideEffect.Right)
  15. }

以上代碼則完整的定義了所有可能的頁(yè)面轉(zhuǎn)場(chǎng)樣式。假設(shè)頁(yè)面棧為標(biāo)準(zhǔn)實(shí)例模式,即頁(yè)面棧中允許存在重復(fù)的頁(yè)面??赡軙?huì)有4種場(chǎng)景,對(duì)應(yīng)的頁(yè)面轉(zhuǎn)場(chǎng)效果如下表。

路由操作

頁(yè)面A轉(zhuǎn)場(chǎng)效果

頁(yè)面B轉(zhuǎn)場(chǎng)效果

router.pushUrl,從頁(yè)面A跳轉(zhuǎn)到新增的頁(yè)面B

頁(yè)面退出,PageTransitionExit且type為RouteType.Push的轉(zhuǎn)場(chǎng)樣式生效,向左側(cè)滑出屏幕

頁(yè)面進(jìn)入,PageTransitionEnter且type為RouteType.Push的轉(zhuǎn)場(chǎng)樣式生效,從右側(cè)滑入屏幕

router.back,從頁(yè)面B返回到頁(yè)面A

頁(yè)面進(jìn)入,PageTransitionEnter且type為RouteType.Pop的轉(zhuǎn)場(chǎng)樣式生效,從左側(cè)滑入屏幕

頁(yè)面退出,PageTransitionExit且type為RouteType.Pop的轉(zhuǎn)場(chǎng)樣式生效,向右側(cè)滑出屏幕

router.pushUrl,從頁(yè)面B跳轉(zhuǎn)到新增的頁(yè)面A

頁(yè)面進(jìn)入,PageTransitionEnter且type為RouteType.Push的轉(zhuǎn)場(chǎng)樣式生效,從右側(cè)滑入屏幕

頁(yè)面退出,PageTransitionExit且type為RouteType.Push的轉(zhuǎn)場(chǎng)樣式生效,向左側(cè)滑出屏幕

router.back,從頁(yè)面A返回到頁(yè)面B

頁(yè)面退出,PageTransitionExit且type為RouteType.Pop的轉(zhuǎn)場(chǎng)樣式生效,向右側(cè)滑出屏幕

頁(yè)面進(jìn)入,PageTransitionEnter且type為RouteType.Pop的轉(zhuǎn)場(chǎng)樣式生效,從左側(cè)滑入屏幕

說(shuō)明

1. 由于每個(gè)頁(yè)面的頁(yè)面轉(zhuǎn)場(chǎng)樣式都可由開發(fā)者獨(dú)立配置,而頁(yè)面轉(zhuǎn)場(chǎng)涉及到兩個(gè)頁(yè)面,開發(fā)者應(yīng)考慮兩個(gè)頁(yè)面的頁(yè)面轉(zhuǎn)場(chǎng)效果的銜接,如時(shí)長(zhǎng)盡量保持一致。

2. 如果沒有定義匹配的頁(yè)面轉(zhuǎn)場(chǎng)樣式,則該頁(yè)面使用系統(tǒng)默認(rèn)的頁(yè)面轉(zhuǎn)場(chǎng)樣式。

禁用某頁(yè)面的頁(yè)面轉(zhuǎn)場(chǎng)

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

通過設(shè)置頁(yè)面轉(zhuǎn)場(chǎng)的時(shí)長(zhǎng)為0,可使該頁(yè)面無(wú)頁(yè)面轉(zhuǎn)場(chǎng)動(dòng)畫。

場(chǎng)景示例

下面介紹定義了所有的四種頁(yè)面轉(zhuǎn)場(chǎng)樣式的頁(yè)面轉(zhuǎn)場(chǎng)動(dòng)畫示例。

  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) // 同步加載圖片,使頁(yè)面出現(xiàn)時(shí)圖片已經(jīng)加載完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一個(gè)頁(yè)面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionDst1' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一頁(yè)面,相當(dāng)于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定義頁(yè)面進(jìn)入時(shí)的效果,從右側(cè)滑入,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  32. PageTransitionEnter({ type: RouteType.Push, duration: 1000 })
  33. .slide(SlideEffect.Right)
  34. // 定義頁(yè)面進(jìn)入時(shí)的效果,從左側(cè)滑入,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  35. PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })
  36. .slide(SlideEffect.Left)
  37. // 定義頁(yè)面退出時(shí)的效果,向左側(cè)滑出,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  38. PageTransitionExit({ type: RouteType.Push, duration: 1000 })
  39. .slide(SlideEffect.Left)
  40. // 定義頁(yè)面退出時(shí)的效果,向右側(cè)滑出,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  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) // 同步加載圖片,使頁(yè)面出現(xiàn)時(shí)圖片已經(jīng)加載完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一頁(yè)面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionSrc1' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一頁(yè)面,相當(dāng)于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定義頁(yè)面進(jìn)入時(shí)的效果,從右側(cè)滑入,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  32. PageTransitionEnter({ type: RouteType.Push, duration: 1000 })
  33. .slide(SlideEffect.Right)
  34. // 定義頁(yè)面進(jìn)入時(shí)的效果,從左側(cè)滑入,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  35. PageTransitionEnter({ type: RouteType.Pop, duration: 1000 })
  36. .slide(SlideEffect.Left)
  37. // 定義頁(yè)面退出時(shí)的效果,向左側(cè)滑出,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生push操作時(shí)該效果才生效
  38. PageTransitionExit({ type: RouteType.Push, duration: 1000 })
  39. .slide(SlideEffect.Left)
  40. // 定義頁(yè)面退出時(shí)的效果,向右側(cè)滑出,時(shí)長(zhǎng)為1000ms,頁(yè)面棧發(fā)生pop操作時(shí)該效果才生效
  41. PageTransitionExit({ type: RouteType.Pop, duration: 1000 })
  42. .slide(SlideEffect.Right)
  43. }
  44. }

下面介紹使用了type為None的頁(yè)面轉(zhuǎn)場(chǎng)動(dòng)畫示例。

  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) // 同步加載圖片,使頁(yè)面出現(xiàn)時(shí)圖片已經(jīng)加載完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一頁(yè)面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionDst2' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一頁(yè)面,相當(dāng)于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定義頁(yè)面進(jìn)入時(shí)的效果,從左側(cè)滑入,時(shí)長(zhǎng)為1000ms,無(wú)論頁(yè)面棧發(fā)生push還是pop操作均可生效
  32. PageTransitionEnter({ duration: 1000 })
  33. .slide(SlideEffect.Left)
  34. // 定義頁(yè)面退出時(shí)的效果,相對(duì)于正常頁(yè)面位置x方向平移100vp,y方向平移100vp,透明度變?yōu)?,時(shí)長(zhǎng)為1200ms,無(wú)論頁(yè)面棧發(fā)生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) // 同步加載圖片,使頁(yè)面出現(xiàn)時(shí)圖片已經(jīng)加載完成
  13. .margin(30)
  14. Row({ space: 10 }) {
  15. Button("pushUrl")
  16. .onClick(() => {
  17. // 路由到下一頁(yè)面,push操作
  18. router.pushUrl({ url: 'pages/myTest/pageTransitionSrc2' });
  19. })
  20. Button("back")
  21. .onClick(() => {
  22. // 返回到上一頁(yè)面,相當(dāng)于pop操作
  23. router.back();
  24. })
  25. }.justifyContent(FlexAlign.Center)
  26. }
  27. .width("100%").height("100%")
  28. .alignItems(HorizontalAlign.Center)
  29. }
  30. pageTransition() {
  31. // 定義頁(yè)面進(jìn)入時(shí)的效果,從左側(cè)滑入,時(shí)長(zhǎng)為1200ms,無(wú)論頁(yè)面棧發(fā)生push還是pop操作均可生效
  32. PageTransitionEnter({ duration: 1200 })
  33. .slide(SlideEffect.Left)
  34. // 定義頁(yè)面退出時(shí)的效果,相對(duì)于正常頁(yè)面位置x方向平移100vp,y方向平移100vp,透明度變?yōu)?,時(shí)長(zhǎng)為1000ms,無(wú)論頁(yè)面棧發(fā)生push還是pop操作均可生效
  35. PageTransitionExit({ duration: 1000 })
  36. .translate({ x: 100.0, y: 100.0 })
  37. .opacity(0)
  38. }
  39. }

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)