HarmonyOS开发中Dialog与页面关系处理,如何避免Dialog重复打开?

一共有两个页面,A页面、B页面
让A页面弹出一个CustomDialog,然后push到B页面,再返回A页面,刷新dialog数据

目前:
1、进入B页面前,会将dialog进行close(如果不close,进入B页面后,dialog依然存在)
2、从B页面返回A页面时,会再次打开dialog(因为有再次打开dialog的操作,对用户不友好)

期望:
A进入B前,不需要close掉dialog;B返回A后,不需要再次打开dialog

问题:
为什么dialog会比页面高一个等级呢?A页面的dialog理应只属于A?为什么进入B页面后,还存在呢?

阅读 1k
1 个回答

使用NavDestination的Dialog模式实现自定义弹窗,可以参考如下demo:

interface RouterParams { 
  name?: string, 
  onPop?: (data: PopInfo) => void 
} 
 
// 封装路由工具类,并注册自定义弹窗组件 
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(); 
  } 
} 
 
@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(() => { 
          AppRouter.pop(); 
        }) 
 
        Column() { 
          Text("dialogA") 
            .fontColor(Color.White) 
          Button("push pageC", { stateEffect: true, type: ButtonType.Capsule }) 
            .onClick(() => { 
              AppRouter.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 
struct PageA { 
  @Consume('pageInfos') pageInfos: NavPathStack; 
 
  build() { 
    NavDestination() { 
      Button('push dialogA', { stateEffect: true, type: ButtonType.Capsule }) 
        .onClick(() => { 
          AppRouter.openDialog("DefaultDialog"); 
        }).margin(10) 
    }.title('PageA') 
  } 
} 
 
@Component 
struct PageC { 
  @Consume('pageInfos') pageInfos: NavPathStack; 
 
  build() { 
    NavDestination() { 
      Column() { 
        Text('pageC') 
          .margin(10) 
        Button('返回', { stateEffect: true, type: ButtonType.Capsule }) 
          .onClick(() => { 
            AppRouter.pop(); 
          }).margin(10) 
      } 
    }.mode(NavDestinationMode.STANDARD) 
  } 
} 
 
@Entry 
@Component 
struct pageRoot01 { 
  @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack() 
  // 显隐控制设置为不占用 
  @State visible: Visibility = Visibility.None 
 
  @Builder 
  PagesMap(name: string) { 
    if (name == 'pageA') { 
      PageA() 
    } else if (name == 'pageC') { 
      PageC() 
    } else if (name == 'DefaultDialog') { 
      DefaultDialog() 
    } 
  } 
 
  build() { 
    // 在根页面中注册NavPathStack 
    Navigation(AppRouter.getInstance().getPathStack()) { 
      Stack({ alignContent: Alignment.Center }) { 
        Column() { 
          Button('push PageA', { stateEffect: true, type: ButtonType.Capsule }) 
            .onClick(() => { 
              AppRouter.push('pageA') 
            }) 
        } 
      } 
      .height("100%") 
      .width("100%") 
    } 
    .hideTitleBar(true) 
    .navDestination(this.PagesMap) 
  } 
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进