HarmonyOS 鸿蒙Next 使用PromptActionManagerInstance.showPrompt展示弹窗时页面跳转问题 HarmonyOS 鸿蒙Next 如何实现在使用PromptActionManagerInstance.showPrompt展示弹窗后,让新页面盖在弹窗上面而非插在旧页面与弹窗之间

发布于 1周前 作者 nodeper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 使用PromptActionManagerInstance.showPrompt展示弹窗时页面跳转问题
HarmonyOS 鸿蒙Next 如何实现在使用PromptActionManagerInstance.showPrompt展示弹窗后,让新页面盖在弹窗上面而非插在旧页面与弹窗之间

使用PromptActionManagerInstance.showPrompt展示弹窗,并在弹窗里进行页面跳转。新的页面会插在旧页面和弹窗之间。希望新的页面能盖在弹窗上面,如何做?

3 回复
demo可参考:
interface RouterParams {
  name?: string,
  onPop?: (data: PopInfo) => void
}
// 封装路由工具类,并注册自定义弹窗组件
class AppRouters {
  private static instance = new AppRouters();
  private pathStack: NavPathStack = new NavPathStack();
  public static getInstance(): AppRouters {
    return AppRouters.instance;
  }
  public getPathStack(): NavPathStack {
    return this.pathStack;
  }
  private pushPath(name: string): void {
    this.pathStack.pushPath({ name: name })
  }
  public static push(name: string): void {
    AppRouters.instance.pushPath(name);
  }
  public static openDialog(name: string, params?: RouterParams): void {
    AppRouters.instance.pathStack.pushPath({
      name: name, param: params, onPop: (data: PopInfo) => {
        if (params?.onPop) {
          params.onPop!(data);
        }
      }
    });
  }
  public static pop(): void {
    AppRouters.instance.pathStack.pop();
  }
}
[@Component](/user/Component)
  // NavDestinationMode.DIALOG
struct DefaultDialog {
  build() {
    NavDestination() {
      Stack({ alignContent: Alignment.Center }) {
        Column() {
        }
        .width("100%")
        .height("100%")
        .backgroundColor('rgba(0,0,0,0.5)')
        .transition(
          TransitionEffect.OPACITY.animation({
            duration: 300,
            curve: Curve.Friction
          })
        )
        .onClick(() => {
          AppRouters.pop();
        })
        Column() {
          Text("dialogA")
            .fontColor(Color.White)
          Button("push pageC", { stateEffect: true, type: ButtonType.Capsule })
            .onClick(() => {
              AppRouters.push("pageC")
            })
        }
        .width("50%")
        .height("30%")
        .backgroundColor('#ffae2d2d')
        .transition(
          TransitionEffect.scale({ x: 0, y: 0 }).animation({
            duration: 300,
            curve: Curve.Friction
          })
        )
      }
      .width("100%")
      .height("100%")
    }
    .mode(NavDestinationMode.DIALOG)
    .hideTitleBar(true)
  }
}
[@Component](/user/Component)
struct PageA {
  [@Consume](/user/Consume)('pageInfos') pageInfos: NavPathStack;
  build() {
    NavDestination() {
      Button('push dialogA', { stateEffect: true, type: ButtonType.Capsule })
        .onClick(() => {
          AppRouters.openDialog("DefaultDialog");
        }).margin(10)
    }.title('PageA')}
}
[@Component](/user/Component)
struct PageC {
  [@Consume](/user/Consume)('pageInfos') pageInfos: NavPathStack;
  build() {
    NavDestination() {
      Column() {
        Text('pageC')
          .margin(10)
        Button('返回', { stateEffect: true, type: ButtonType.Capsule })
          .onClick(() => {
            AppRouters.pop();
          }).margin(10)
      }
    }.mode(NavDestinationMode.STANDARD)
  }
}
[@Entry](/user/Entry)
[@Component](/user/Component)
struct pageRoot01 {
  [@Provide](/user/Provide)('pageInfos') pageInfos: NavPathStack = new NavPathStack()
  // 显隐控制设置为不占用
  [@State](/user/State) visible: Visibility = Visibility.None
  [@Builder](/user/Builder)
  PagesMap(name: string) {
    if (name == 'pageA') {
      PageA()
    } else if (name == 'pageC') {
      PageC()
    } else if (name == 'DefaultDialog') {
      DefaultDialog()
    }
  }
  build() {
    // 在根页面中注册NavPathStack
    Navigation(AppRouters.getInstance().getPathStack()) {
      Stack({ alignContent: Alignment.Center }) {
        Column() {
          Button('push PageA', { stateEffect: true, type: ButtonType.Capsule })
            .onClick(() => {
              AppRouters.push('pageA')
            })
        }
      }
      .height("100%")
      .width("100%")
    }
    .hideTitleBar(true)
    .navDestination(this.PagesMap)
  }
}
// 封装路由工具类,并注册自定义弹窗组件
class AppRouter {
  private static instance = new AppRouter();
  private pathStack: NavPathStack = new NavPathStack();
  public static getInstance(): AppRouter {
    return AppRouter.instance;
  }
  public getPathStack(): NavPathStack {
    return this.pathStack;
  }
  private pushPath(name: string): void {
    this.pathStack.pushPath({ name: name })
  }
  public static push(name: string): void {
    AppRouter.instance.pushPath(name);
  }
  public static openDialog(name: string, params?: RouterParams): void {
    AppRouter.instance.pathStack.pushPath({
      name: name, param: params, onPop: (data: PopInfo) => {
        if (params?.onPop) {
          params.onPop!(data);
        }
      }
    });
  }
  public static pop(): void {
    AppRouter.instance.pathStack.pop();
  }
}
鸿蒙ArkTS:
// 使用覆盖模式  
router.pushUrl({  
  url: '目标页面路由',  
  params: {},  
  mode: router.RouterMode.Standard, 
  overlayMode: true // 启用覆盖模式  
})

或者强制置顶:
 

[@Styles](/user/Styles) function coverStyle() {  
  .position(Absolute)  
  .zIndex(999)  // 设置最高层级  
  .width('100%')  
  .height('100%')  
}  

@Component
struct TargetPage {
build() {
Column() {
// 页面内容 }
.coverStyle()
}
}

还可以关闭弹窗再操作:

// 先关闭弹窗  
PromptActionManagerInstance.hidePrompt()

// 再跳转页面 router.pushUrl({
url: ‘目标页面路由’
})

主要看你的需求,有帮助的话点个关注哈

在HarmonyOS 鸿蒙Next系统中,当使用PromptActionManagerInstance.showPrompt展示弹窗时,页面跳转的行为通常由系统的UI堆栈管理机制决定。若希望在弹窗显示后,新页面能够覆盖在弹窗之上,而非插入到旧页面与弹窗之间,你需要确保新页面的跳转操作是在弹窗显示逻辑之后,并且系统允许这样的覆盖行为。

一种可能的解决方案是,利用系统的异步机制,在弹窗显示完成后再触发新页面的跳转。你可以通过回调或者监听弹窗的显示状态来实现这一点。不过,由于HarmonyOS的具体API和行为可能有所限制,这种方法不一定总是可行。

另外,检查你的页面跳转代码,确保没有错误地触发了多次跳转,或者跳转逻辑被不当地嵌套在了弹窗显示逻辑的内部。

如果上述方法无法达到预期效果,可能是系统层面的限制。此时,你可以考虑调整UI设计,或者在用户交互上做出妥协,比如先关闭弹窗再进行页面跳转。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部