HarmonyOS鸿蒙Next中实现不关闭弹窗的情况下跳转页面,并且页面返回时弹窗仍不关闭

HarmonyOS鸿蒙Next中实现不关闭弹窗的情况下跳转页面,并且页面返回时弹窗仍不关闭 【问题描述】:新打开的页面是显示在这个弹窗下面的,不关闭弹窗,需要页面返回后弹窗不关闭,levelmode参数是不是没有效果

【问题现象】:弹窗始终在跳转页面的上方,想要实现点击弹窗跳转后,页面返回后弹窗不关闭 cke_8202.png

【版本信息】:未涉及

【复现代码】:https://developer.huawei.com/consumer/cn/doc/architecture-guides/audio-v1_2-ts_36-0000002419471521#section16365310401,该链接的第二种解决方案

【尝试解决方案】:将方案二改成Navigation跳转,但是使用levelmode没有效果,弹窗始终在跳转页面的上方


更多关于HarmonyOS鸿蒙Next中实现不关闭弹窗的情况下跳转页面,并且页面返回时弹窗仍不关闭的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

建议通过Navigation跳转的路由拦截功能,监听页面从新跳转回了当前页面,然后判断是否需要重新弹出你的自定义弹框就行了~

看代码:

//添加路由拦截
this.pathStack.setInterception({
  willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
    operation: NavigationOperation, animated: boolean) => {

    //判断是否是根导航页面,或者是其它的页面
    if (typeof to === "string") {
      console.log("target page is navigation home page.");

      //跳转回了根导航页面,做点什么~
      this.dialogController.open();  //重新弹框

      return;
    }
  }
})

更多关于HarmonyOS鸿蒙Next中实现不关闭弹窗的情况下跳转页面,并且页面返回时弹窗仍不关闭的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我的要求是不关闭弹窗,在我从页面返回的时候弹窗未关闭。但是我使用nav操作,使用levelmode,始终置为新页面的上方,

哎,变通一下的啦,跳转的时候肯定会关闭弹窗的,你只能在回到当前页面的时候再弹一次框!,

在HarmonyOS Next中,可通过windowStage.loadContent加载新页面,同时保持弹窗状态。使用windowStage.setUIContent管理页面层级,确保弹窗组件不被销毁。页面返回时,弹窗因未调用关闭方法而持续显示。需注意页面生命周期与弹窗状态管理,避免内存泄漏。

在HarmonyOS Next中,要实现不关闭弹窗的情况下跳转页面,并且页面返回时弹窗仍不关闭,关键在于正确配置弹窗的模态级别和导航跳转方式。

根据你的描述,使用levelMode参数无效,弹窗始终在跳转页面上方,这通常是因为弹窗的模态级别设置过高,或者导航跳转的目标页面被放置在了弹窗所在的窗口之下。

核心解决方案:

  1. 确保弹窗使用非全屏模态(levelMode: LevelMode.SYSTEM_ALERT或更低级别)

    • 如果弹窗的levelMode设置为LevelMode.SYSTEM_ALERT(系统告警窗口)或更低(如LevelMode.OVERLAY),它默认会显示在应用内所有页面之上。但当你进行页面跳转时,新的页面可能会被创建在一个新的、更顶层的窗口栈中,从而导致弹窗被覆盖。
    • 关键点:要实现“页面在弹窗之下”的效果,需要确保导航跳转的目标页面与弹窗宿主页面处于同一个UIAbility上下文和窗口栈中,并且弹窗的模态级别不能阻止页面跳转的渲染层。
  2. 使用正确的导航方式并传递正确的上下文

    • 在弹窗组件内部触发页面跳转时,必须获取到当前Ability的UI上下文(UIContext),并将其传递给导航器。
    • 示例代码片段(ArkTS)
      // 在弹窗组件内部
      import { router } from '@kit.ArkUI';
      
      @CustomDialog
      struct MyDialog {
        // 1. 注入当前UI上下文
        private uiContext: UIContext = getUIContext();
      
        build() {
          Column() {
            Button('跳转到新页面')
              .onClick(() => {
                // 2. 使用获取到的uiContext进行跳转
                router.pushUrl({
                  url: 'pages/NewPage',
                  // 3. 设置params,传递uiContext(如果需要在新页面操作)
                  params: { sourceUIContext: this.uiContext }
                }, this.uiContext); // 将uiContext作为第二个参数传递
              })
          }
        }
      }
      
    • 通过将uiContext传递给router.pushUrl,可以确保新页面在同一个窗口栈中被打开,从而允许弹窗(如果其levelMode设置得当)保持在顶层。
  3. 检查弹窗的levelMode与页面路由的兼容性

    • 如果上述方法仍不生效,可以尝试将弹窗的levelMode设置为LevelMode.OVERLAY。这个级别的弹窗更像是“覆盖层”,可能更容易与页面导航共存。但需要注意,OVERLAY级别可能在某些系统场景下受限。
    • 同时,检查是否在页面跳转时,目标页面被错误地配置为了全屏或新的透明窗口(例如,通过window模块设置了错误属性)。
  4. 替代方案:使用PageTransitionDialog

    • 如果业务场景是弹窗作为页面的一部分,并且伴随页面跳转和返回,可以考虑使用@ohos.arkui.advanced.CustomDialogController配合页面生命周期,在pageA跳转至pageB时,在pageAaboutToDisappear中隐藏弹窗,在pageAaboutToAppear中重新显示。但这需要更精细的状态管理。

总结步骤:

  • 确认弹窗使用LevelMode.SYSTEM_ALERTLevelMode.OVERLAY
  • 在弹窗内跳转时,务必通过getUIContext()获取当前UI上下文,并将其作为参数传递给router.pushUrl()
  • 确保没有其他全局窗口配置干扰了页面层叠关系。

如果问题依旧,请检查router.pushUrl的调用是否确实发生在弹窗的UI上下文中,并确认目标页面的窗口属性。

回到顶部