HarmonyOS Navigation转场动画能否只对单个页面使用自定义转场动画

为实现转场动画而参考下文:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5#%E7%A4%BA%E4%BE%8B3

但是此处存在一个疑问:

如果customNavContentTransition返回为undefined,则使用系统默认转场动画

如果customNavContentTransition返回了NavigationAnimatedTransition对象,则必须同时注册fromParam和toParam才能使from页面和to页面有动画。但是,假如我想要from页面保持默认动画,to页面使用自定义动画,则无法做到。这该怎么处理

HarmonyOS
2024-12-25 07:45:43
447浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
Heiang

页面打开顺序是 A -> B -> C

操作步骤一:A 打开B时,A不动,B升起,B返回A时,B降下,A不动

操作步骤二:B打开C,使用默认的推入推出动画,C返回B也是默认动画

针对操作步骤一,通过自定义转场实现,分别定义a、b页面转场动画

针对操作步骤二,customNavContentTransition返回undefined

// Index.ets
import { CustomTransition, AnimateCallback } from './CustomNavigationUtils'

@Entry
@Component
struct NavigationExample {
  @Provide('NavPathStack') pageInfos: NavPathStack = new NavPathStack()

  aboutToAppear() {
    if (this.pageInfos === undefined) {
      this.pageInfos = new NavPathStack();
    }
    this.pageInfos.pushPath({ name: 'pageOne1' }, false)
  }

  build() {
    Navigation(this.pageInfos) {
    }.title('NavIndex')
    .hideNavBar(true)
    .customNavContentTransition((from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => {
      if (from.mode == NavDestinationMode.DIALOG || to.mode == NavDestinationMode.DIALOG) {
        return undefined;
      }
      console.log(`current info: ${to.name}, index: ${to.index}, mode: ${to.mode}`);
      console.log(`pre info: ${from.name}, index: ${from.index}, mode: ${from.mode}`);
      console.log(`operation: ${operation}`)
      if (from.index === -1 || to.index === -1) {
        return undefined;
      }
      if(from.name == 'pageThree1' || to.name == 'pageThree1') { // b进入c页面或者c返回b页面
        return undefined;
      }
      let customAnimation: NavigationAnimatedTransition = {
        onTransitionEnd: (isSuccess: boolean) => {
          console.log(`current transition result is ${isSuccess}`);
        },
        timeout: 700,
        // 转场开始时系统调用该方法,并传入转场上下文代理对象
        transition: (transitionProxy: NavigationTransitionProxy) => {
          console.log("trigger transition callback");
          // 从封装类CustomTransition中根据子页面的序列获取对应的转场动画回调
          let fromParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(from.index);
          let toParam: AnimateCallback = CustomTransition.getInstance().getAnimateParam(to.index);
          if (fromParam.start != undefined) {
            fromParam.start(operation == NavigationOperation.PUSH, true);
          }
          if (toParam.start != undefined) {
            toParam.start(operation == NavigationOperation.PUSH, false);
          }
          //自定义转场动画,转场开始时系统调用
          animateTo(
            {
              duration: 1000,
              onFinish: () => {
                if (fromParam.onFinish != undefined) {
                  fromParam.onFinish(operation === NavigationOperation.PUSH, true);
                }
                if (toParam.onFinish != undefined) {
                  toParam.onFinish(operation === NavigationOperation.PUSH, true);
                }
                transitionProxy.finishTransition();
              }
            },
            () => {
              if (fromParam.finish != undefined) {
                fromParam.finish(operation === NavigationOperation.PUSH, true);
              }
              if (toParam.finish != undefined) {
                toParam.finish(operation === NavigationOperation.PUSH, false);
              }
            })
        }
      };
      return customAnimation;
    })
  }
}


// PageOne.ets
import { CustomTransition } from './CustomNavigationUtils'

@Builder
export function PageOneBuilder(name: string, param: Object) {
  PageOne1()
}

@Component
export struct PageOne1 {
  @Consume('NavPathStack') pageInfos: NavPathStack
  @State x: number = 0
  @State scaleVal: number = 1
  pageId: number = 0;

  aboutToAppear() {
    this.pageId = this.pageInfos.getAllPathName().length - 1;
    CustomTransition.getInstance().registerNavParam(
      this.pageId,
      (isPush: boolean, isExit: boolean) => {
        console.log('pagestart One ')
        this.x = isExit ? 0 : 300;
      },
      (isPush: boolean, isExit: boolean) => {
        console.log('pagefinish One')
        this.x = isExit ? -300 : 0;
      },
      (isPush: boolean, isExit: boolean) => {
        console.log('pageonfinish One ')
        this.x = 0;
      },
      200
    );
  }

  build() {
    NavDestination() {
      Column() {
        Text('p1X:' + this.x)
        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPathByName('pageTwo1', null) //将name指定的NavDestination页面信息入栈,传递的数据为param
          })
      }.width('100%').height('100%')
    }
    .title('PageOne1')
    .mode(NavDestinationMode.STANDARD)
    .onBackPressed(() => {
      const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素
      console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))
      return true
    })
    .onDisAppear(() => {
      CustomTransition.getInstance().unRegisterNavParam(this.pageId)
    })
    .onReady((context: NavDestinationContext) => {
      this.pageInfos = context.pathStack
    })
    // .translate({ x: this.x, y: 0, z: 0 })
    .backgroundColor(Color.White)
  }
}


// PageTwo.ets
import { CustomTransition } from './CustomNavigationUtils'

@Builder
export function PageTwoBuilder(name: string, param: Object) {
  PageTwo1()
}

@Component
export struct PageTwo1 {
  @Consume('NavPathStack') pageInfos: NavPathStack
  @State x: number = 300
  @State y: number = 300
  pageId: number = 0

  aboutToAppear() {
    this.pageId = this.pageInfos.getAllPathName().length - 1;
    CustomTransition.getInstance().registerNavParam(
      this.pageId,
      (isPush: boolean, isExit: boolean) => {
        console.log('pagestart Two ')
        // this.x = isExit ? 0 : isPush ? 300 : -300;
        if (isExit) {
          if (!isPush) { // b回a
            this.x = 0;
            this.y = 0;
          }
        } else {
          if (isPush) { // a到b
            this.x = 0;
            this.y = 300;
          }
        }
      },
      (isPush: boolean, isExit: boolean) => {
        console.log('pagefinish Two ')
        // this.x = isExit ? isPush ? -300 : 300 : 0;
        if (isExit) {
          if (!isPush) { // b回a
            this.x = 0;
            this.y = 300;
          }
        } else {
          if (isPush) { // a到b
            this.x = 0;
            this.y = 0;
          }
        }
      },
      (isPush: boolean, isExit: boolean) => {
        console.log('pageonfinish Two')
        this.x = 0;
        this.y = 0;
      },
      10000
    )
  }

  build() {
    NavDestination() {
      Column() {
        Text('p2X:' + this.x)
        Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPathByName('pageThree1', null) //将name指定的NavDestination页面信息入栈,传递的数据为param
          })
      }.width('100%').height('100%')
    }
    .title('PageTwo1')
    .onBackPressed(() => {
      const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素
      console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))
      return true
    })
    .onDisAppear(() => {
      CustomTransition.getInstance().unRegisterNavParam(this.pageId)
    })
    .onReady((context: NavDestinationContext) => {
      this.pageInfos = context.pathStack;
    })
    // .opacity(0.5)
    .translate({ x: this.x, y: this.y })
    .backgroundColor(Color.White)
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
分享
微博
QQ
微信
回复
2024-12-25 09:46:41


相关问题
Navigation如何自定义立体转场动画
340浏览 • 1回复 待解决
自定义弹窗自定义转场动画
1984浏览 • 1回复 待解决
HarmonyOS navigation导航转场动画怎么写
745浏览 • 1回复 待解决
HarmonyOS Navigation实现Dialog转场动画
712浏览 • 1回复 待解决
如何全局设置页面转场动画
1226浏览 • 1回复 待解决
HarmonyOS Refresh和页面转场动画demo
668浏览 • 1回复 待解决
HarmonyOS 页面内的组件转场动画
1095浏览 • 1回复 待解决
HarmonyOS Navigation转场动画的一些思路
717浏览 • 1回复 待解决
HarmonyOS SideBarContainer 转场动画
551浏览 • 1回复 待解决
如何实现动画转场效果
1782浏览 • 1回复 待解决
HarmonyOS 如何自定义导航转场
975浏览 • 1回复 待解决
Tabs 出现/消失转场动画效果
1108浏览 • 1回复 待解决
HarmonyOS 无感转场动画推荐方案
846浏览 • 1回复 待解决