HarmonyOS Naviagtion动画问题咨询

UI展示使用的是Navigation和NavDestination的跳转方式。其中跳转动画用的是customNavContentTransition,如何实现跳转动画是从0到1渐变出现整个页面,而不是默认从左到右的动画。

HarmonyOS
1天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
Excelsior_abit

请参考示例如下:

interface AnimateCallback {
  finish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined;
  start: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined;
  onFinish: ((isPush: boolean, isExit: boolean) => void | undefined) | undefined;
  timeout: (number | undefined) | undefined;
}

const customTransitionMap: Map<number, AnimateCallback> = new Map();

export class CustomTransition {
  private constructor() {
  }

  static delegate = new CustomTransition();

  static getInstance() {
    return CustomTransition.delegate;
  }

  registerNavParam(name: number, startCallback: (operation: boolean, isExit: boolean) => void,
    endCallback: (operation: boolean, isExit: boolean) => void,
    onFinish: (operation: boolean, isExit: boolean) => void, timeout: number): void {
    console.log("tag registerNavParam");
    if (customTransitionMap.has(name)) {
      let param = customTransitionMap.get(name);
      if (param != undefined) {
        param.start = startCallback;
        param.finish = endCallback;
        param.onFinish = onFinish;
        param.timeout = timeout;
        return;
      }
    }
    let params: AnimateCallback = {
      timeout: timeout,
      start: (isPush, isExit) => {
        startCallback(isPush, isExit);
        this.setOpacity(isExit ? 0 : 1); // 设置透明度
      },
      finish: (isPush, isExit) => {
        endCallback(isPush, isExit);
        this.setOpacity(isExit ? 0 : 1); // 设置透明度
      },
      onFinish: (isPush, isExit) => {
        onFinish(isPush, isExit);
        this.setOpacity(1); // 重置透明度
      }
    };
    customTransitionMap.set(name, params);
  }

  unRegisterNavParam(name: number): void {
    console.log("tag unRegisterNavParam");
    customTransitionMap.delete(name);
  }

  getAnimateParam(name: number): AnimateCallback {
    console.log("tag unRegisterNavParam");
    let result: AnimateCallback = {
      start: customTransitionMap.get(name)?.start,
      finish: customTransitionMap.get(name)?.finish,
      timeout: customTransitionMap.get(name)?.timeout,
      onFinish: customTransitionMap.get(name)?.onFinish
    };
    return result;
  }

  setOpacity(opacity: number) {
    // 实现设置透明度的方法
  }
}

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

  @Builder
  PageMap(name: string) {
    if (name === 'pageOne') {
      pageOneTmp({ pageId: Date.now() })
    } else if (name === 'pageTwo') {
      PageTwoTemp({ pageId: Date.now() })
    }
  }

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

  build() {
    Navigation(this.pageInfos) {
    }.title('NavIndex').navDestination(this.PageMap)
    .hideNavBar(true)
    .customNavContentTransition((from: NavContentInfo, to: NavContentInfo, operation: NavigationOperation) => {
      if (from.mode == NavDestinationMode.DIALOG || to.mode == NavDestinationMode.DIALOG) {
        return undefined;
      }
      console.log(`tag info: ${to.name}, index: ${to.index}, mode: ${to.mode}`);
      console.log(`tag pre info: ${from.name}, index: ${from.index}, mode: ${from.mode}`);
      console.log(`tag operation: ${operation}`)
      if (from.index === -1 || to.index === -1) {
        console.log("tag undefined")
        return undefined;
      }
      let customAnimation: NavigationAnimatedTransition = {
        onTransitionEnd: (isSuccess: boolean) => {
          console.log(`tag current transition result is ${isSuccess}`);
        },
        timeout: 700,
        transition: (transitionProxy: NavigationTransitionProxy) => {
          console.log("tag trigger transition callback");
          let fromParam: AnimateCallback = CustomTransition.getInstance()?.getAnimateParam(from.index);
          let toParam: AnimateCallback = CustomTransition.getInstance()?.getAnimateParam(to.index);
          if (fromParam.start != undefined) {
            console.log("tag fromParam.start");
            fromParam.start(operation == NavigationOperation.PUSH, true);
          }
          if (toParam.start != undefined) {
            console.log("tag toParam.start");
            toParam.start(operation == NavigationOperation.PUSH, false);
          }
          animateTo({
            duration: 1200, onFinish: () => {
              console.log("tag animateTo start");
              if (fromParam.onFinish != undefined) {
                console.log("tag fromParam onFinish");
                fromParam.onFinish(operation === NavigationOperation.PUSH, true);
              }
              if (toParam.onFinish != undefined) {
                console.log("tag toParam onFinish");
                toParam.onFinish(operation === NavigationOperation.PUSH, false);
              }
              transitionProxy.finishTransition();
            }
          }, () => {
            if (fromParam.finish != undefined) {
              console.log("tag fromParam finish");
              fromParam?.finish(operation === NavigationOperation.PUSH, true);
            }
            if (toParam.finish != undefined) {
              console.log("tag toParam finish");
              toParam?.finish(operation === NavigationOperation.PUSH, false);
            }
          })
        }
      }
      return customAnimation;
    })
  }
}

@Component
struct pageOneTmp {
  @Consume('pageInfos') pageInfos: NavPathStack
  @State x: number = 0
  @State opacitys: number = 1 // 添加透明度状态
  pageId: number = 0;

  aboutToAppear() {
    this.pageId = this.pageInfos.getAllPathName().length - 1;
    CustomTransition.getInstance().registerNavParam(this.pageId, (isPush: boolean, isExit: boolean) => {
      this.x = isExit ? 0 : 300;
      this.opacitys = isExit ? 1 : 0; // 设置初始透明度
    }, (isPush: boolean, isExit: boolean) => {
      this.x = isExit ? -300 : 0;
      this.opacitys = isExit ? 0 : 1; // 设置结束透明度
    }, (isPush: boolean, isExit: boolean) => {
      console.log("tag PageOne x finish : " + this.x)
      this.x = 0;
      this.opacitys = 1; // 重置透明度
    }, 200);
  }

  build() {
    NavDestination() {
      Column() {
        Button('pageTwo', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.pageInfos.pushPathByName('pageTwo', null) //将name指定的NavDestination页面信息入栈,传递的数据为param
          })

      }.width('100%').height('100%').backgroundColor(Color.Red)
    }
    .title('pageOne')
    .mode(NavDestinationMode.STANDARD)
    .onBackPressed(() => {
      const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素
      console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))
      return true
    })
    .onDisAppear(() => {
      console.log("tag pageone onDisAppear");
      CustomTransition.getInstance().unRegisterNavParam(this.pageId)
    })
    .translate({ x: 0, y: this.x, z: 0 })
    .opacity(this.opacitys) // 设置透明度属性
    .backgroundColor(Color.White)
  }
}

@Component
struct PageTwoTemp {
  @Consume('pageInfos') pageInfos: NavPathStack
  @State x: number = 300
  @State opacitys: number = 1 // 添加透明度状态
  pageId: number = 0;

  aboutToAppear() {
    this.pageId = this.pageInfos.getAllPathName().length - 1;
    CustomTransition.getInstance().registerNavParam(this.pageId, (isPush: boolean, isExit: boolean) => {
      this.x = isExit ? 0 : isPush ? 300 : -300;
      this.opacitys = isExit ? 1 : 0; // 设置初始透明度
      console.log("tag PageTwo x start is : " + this.x)
    }, (isPush: boolean, isExit: boolean) => {
      this.x = isExit ? isPush ? -300 : 300 : 0;
      this.opacitys = isExit ? 0 : 1; // 设置结束透明度
      console.log("tag PageTwo x end is : " + this.x)
    }, (isPush: boolean, isExit: boolean) => {
      this.x = 0;
      this.opacitys = 1; // 重置透明度
      console.log("tag PageTwo x finish : " + this.x)
    }, 2000);
  }

  build() {
    NavDestination() {
      Column() {
        Text('Page Two').fontSize(50)
      }.width('100%').height('100%').backgroundColor(Color.Blue)
    }
    .title('pageTwo')
    .onBackPressed(() => {
      console.log("tag pagetwo onBackPressed");
      const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素
      console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo))
      return true
    })
    .onDisAppear(() => {
      console.log("tag pagetwo onDisAppear");
      CustomTransition.getInstance().unRegisterNavParam(this.pageId)
    })
    .translate({ x: 0, y: 0, z: this.x })
    .opacity(this.opacitys) // 设置透明度属性
    .backgroundColor(Color.White)
  }
}
分享
微博
QQ
微信
回复
1天前
相关问题
HarmonyOS卡片问题咨询
338浏览 • 1回复 待解决
HarmonyOS Image问题咨询
8浏览 • 1回复 待解决
HarmonyOS precompileJavaScript 问题咨询
102浏览 • 1回复 待解决
HarmonyOS 画布问题咨询
265浏览 • 1回复 待解决
HarmonyOS 录像问题咨询
463浏览 • 1回复 待解决
mapkitxiang 问题咨询
325浏览 • 1回复 待解决
HarmonyOS 系统picker问题咨询
465浏览 • 1回复 待解决
HarmonyOS 地点类型问题咨询
35浏览 • 1回复 待解决
HarmonyOS 网络相关问题咨询
53浏览 • 1回复 待解决
HarmonyOS 崩溃收集问题咨询
501浏览 • 1回复 待解决
HarmonyOS image resizable问题咨询
446浏览 • 1回复 待解决
HarmonyOS AOT相关问题咨询
426浏览 • 1回复 待解决
HarmonyOS 媒体问题相关咨询
227浏览 • 1回复 待解决
HarmonyOS taskpool使用问题咨询
215浏览 • 1回复 待解决
HarmonyOS getRawFileContent使用问题咨询
636浏览 • 1回复 待解决
HarmonyOS reactnative版本问题咨询
21浏览 • 1回复 待解决
HarmonyOS 应用权限问题咨询
27浏览 • 1回复 待解决
HarmonyOS app安装问题咨询
36浏览 • 1回复 待解决
HarmonyOS 相机权限问题咨询
72浏览 • 1回复 待解决
jsBridge相关问题咨询
457浏览 • 1回复 待解决
requestInStream使用问题咨询
803浏览 • 1回复 待解决
AppGallery Connect问题咨询
367浏览 • 1回复 待解决
HarmonyOS 音频播放相关问题咨询
220浏览 • 1回复 待解决
HarmonyOS 上架权限问题咨询
105浏览 • 1回复 待解决
提问
该提问已有0人参与 ,帮助了0人