从下往上打开效果的页面转场动画请参考如下demo//Index.ets import { promptAction } from '@kit.ArkUI'; import { Page01 } from '../components/Page01'; import { Page02 } from '../components/Page02'; import { Page03 } from '../components/Page03'; import { AnimateCallback, CustomTransition } from './CustomNavigationUtils'; export class Pages { names: string = "" values: NavPathStack | null = null } export const pagesUserName: Array<string> = ['Page01', 'Page02', 'Page03']; @Entry @Component struct Index { @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack() aboutToAppear(): void { // this.pageInfos.disableAnimation(true) } @Builder PageMap(name: string) { if (name==='Page01') { Page01() } else if (name==='Page02') { Page02() } else if (name==='Page03') { Page03() } } build() { Navigation(this.pageInfos) { Button('pushPath', {type: ButtonType.Capsule }) .width('80%') .height(40) .margin(20) .onClick(() => { // 关闭入场动画 // this.pageInfos.pushPathByName( 'Page01',null,false) this.pageInfos.pushPathByName( 'Page01',null) //将name指定的NavDestination页面信息入栈 }) }.title('NavIndex').navDestination(this.PageMap) //转场协议对象 .customNavContentTransition((from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) =>{ // Push时,不需要播放来自页面的动画,因为它还在栈中 let animateFormId: string = (from.name == null || operation == NavigationOperation.PUSH) ? 'null' : from.name; // Pop时,不需要播放去往页面的动画,因为它还在栈中 let animateToId: string = (to.name == null || operation == NavigationOperation.POP) ? 'null' : to.name; // 如果两个页面都没有自定义动画,那么就播放默认动画 if (!CustomTransition.getInstance().hasAnimateParam(animateFormId) && !CustomTransition.getInstance().hasAnimateParam(animateToId)) { promptAction.showToast({ message: '没找到动画' }); return undefined; } let customAnimation: NavigationAnimatedTransition = { onTransitionEnd: (isSuccess: boolean)=>{ }, // timeout: operation == NavigationOperation.REPLACE ? 2000 : 1000, //自定义的转场动画方法 transition: (transitionProxy: NavigationTransitionProxy) => { let fromParam: AnimateCallback | undefined = CustomTransition.getInstance().getAnimateParam(animateFormId); let toParam: AnimateCallback | undefined = CustomTransition.getInstance().getAnimateParam(animateToId); fromParam?.start(operation == NavigationOperation.PUSH, true); toParam?.start(operation == NavigationOperation.PUSH, false); animateTo({ duration: operation == NavigationOperation.REPLACE ? 2000 : 1000, onFinish: () => { //通知组件,此页面的自定义动画已结束 transitionProxy.finishTransition(); }}, () => { fromParam?.finish(operation === NavigationOperation.PUSH, true) toParam?.finish(operation === NavigationOperation.PUSH, false); }) } }; promptAction.showToast({ message: '播放动画' }); return customAnimation; }) .height('100%') .width('100%') } } //page01.ets import { CustomTransition } from '../pages/CustomNavigationUtils'; import { Pages } from '../pages/Index'; @Component export struct Page01{ @Consume('pageInfos') pageInfos: NavPathStack; @State translateY: string | number = 0; aboutToAppear() { // 注册动画 CustomTransition.getInstance().registerTransitionParam("Page01", (isPush: boolean, isExit: boolean) => { // 开始时,若为入场,则 this.translateY = isExit ? '0%' : '100%'; }, (isPush: boolean, isExit: boolean) => { //出场 this.translateY = isExit ? '100%' : '0%'; }, 1000); } aboutToDisappear() { CustomTransition.getInstance().unregisterTransitionParam("Page01") } build(){ NavDestination() { Column() { Button('pushPathByName', { type: ButtonType.Capsule }) .width('80%') .height(40) .margin(20) .onClick(() => { this.pageInfos.pushPathByName('Page02',null) //将name指定的NavDestination页面信息入栈,传递的数据为param }) }.width('100%').height('100%') }.title('page01') .translate({x: 0, y: this.translateY}) .onBackPressed(() => { //如返回的时候需要转场动画就把false去掉 const popDestinationInfo = this.pageInfos.pop(false) // 弹出路由栈栈顶元素 return true }) } }
从下往上打开效果的页面转场动画请参考如下demo