页面间转场动画 pageTransition

81 阅读2分钟

页面间转场动画 pageTransition

  • 页面转场动画 (不推荐) - 使用router才配置页面转场
  • 两个页面间发生跳转,一个页面消失,另一个页面出现,这时可以配置各自页面的页面转场参数实现自定义的页面转场效果
  • 使用pageTransition通过PageTransitionEnterPageTransitionExit指定页面进入和退出的动画效果
  • PageTransitionEnter 表示入场时起点值
  • PageTransitionExit 表示退场的终点值
  • A页面 push B页面 - 效果为:A退场 B入场
  • B页面 pop A页面 - 效果为:B退场 A入场
// A页面
import { hilog } from '@kit.PerformanceAnalysisKit';
import { router } from '@kit.ArkUI';

@Entry
@ComponentV2
struct PageTransitionPage {
  @Local _opacity: number = 0;
  @Local _x: number = 1

  // 进入此页面或移动到其他页面时实现动画
  pageTransition() {
    // 设置当前页面的自定义入场动效
    PageTransitionEnter({
      duration: 300,
      curve: Curve.Linear,
      delay: 0
    }).onEnter((type: RouteType, progress: number) => {
      // 逐帧回调,直到入场动画结束,progress从0变化到1
      if (type === RouteType.Push) {
        if (progress === 0) {
          hilog.info(0x0123, '', `push => A入场`)
        }
        this._opacity = progress;
        this._x = 1 - progress;
        return;
      }
      if (type === RouteType.Pop) {
        if (progress === 0) {
          hilog.info(0x0123, '', `pop => A入场`)
        }
        this._opacity = progress;
        this._x = 1 - progress;
      }
    })

    // 设置当前页面的自定义退场动效
    PageTransitionExit({
      duration: 300,
      curve: Curve.Linear
    }).onExit((type: RouteType, progress: number) => {
      // 逐帧回调,直到出场动画结束,progress从0变化到1
      if (type === RouteType.Push) {
        if (progress === 0) {
          hilog.info(0x0123, '', `push => A退场`)
        }
        this._opacity = 1 - progress;
        this._x = progress * 0.9;
        return;
      }
      if (type === RouteType.Pop) {
        if (progress === 0) {
          hilog.info(0x0123, '', `pop => A退场`)
        }
        this._opacity = 1 - progress;
        this._x = progress * 0.9;
      }
    })
  }

  build() {
    RelativeContainer() {
      Text("HarmonyOS NEXT")
        .id('PageTransitionPageHelloWorld')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(() => {
          router.pushUrl({
            url: "pages/animation/PageTransitionPageB"
          })
        })
    }
    .height('100%')
    .width('100%')
    .opacity(this._opacity)
    .translate({ y: `${this._x * 100}%` })
  }
}

// B页面
import { router } from '@kit.ArkUI';
import { hilog } from '@kit.PerformanceAnalysisKit';

@Entry
@Component
struct PageTransitionPageB {
  @State message: string = 'Hello World';

  pageTransition() {
    PageTransitionEnter({
      // 页面转场效果生效的路由类型
      type: RouteType.Push,
      duration: 300,
      curve: Curve.Linear
    })
      .onEnter((type: RouteType, progress: number) => {
        if (progress === 0) {
          hilog.info(0x0123, '', `push => B入场`)
        }
      })
      .slide(SlideEffect.Right)

    PageTransitionEnter({
      type: RouteType.Pop,
      duration: 300,
      curve: Curve.Linear
    })
      .onEnter((type: RouteType, progress: number) => {
        if (progress === 0) {
          hilog.info(0x0123, '', `pop => B入场`)
        }
      })
      .slide(SlideEffect.Left)

    PageTransitionExit({
      type: RouteType.Push,
      duration: 300,
      curve: Curve.Linear
    })
      .onExit((type: RouteType, progress: number) => {
        if (progress === 0) {
          hilog.info(0x0123, '', `push => B退场`)
        }
      })
      .slide(SlideEffect.Left)

    PageTransitionExit({
      type: RouteType.Pop,
      duration: 300,
      curve: Curve.Linear
    })
      .onExit((type: RouteType, progress: number) => {
        if (progress === 0) {
          hilog.info(0x0123, '', `pop => B退场`)
        }
      })
      .slide(SlideEffect.Right)
  }

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('PageTransitionPageBHelloWorld')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
        .onClick(() => {
          router.back()
        })
    }
    .height('100%')
    .width('100%')
  }
}