文档管理中心
FAQ应用框架开发UI框架UI界面Dialog弹出多个弹窗后无法关闭

Dialog弹出多个弹窗后无法关闭

问题现象

如何解决弹出多个弹窗,无法关闭的问题?

问题代码示例参考如下:

收起
自动换行
深色代码主题
复制
  1. closeDialog() {
  2. if (DialogUtils.contentNode) {
  3. let uiContext: UIContext | undefined = AppStorage.get<UIContext>('uiContext')
  4. if (uiContext) {
  5. uiContext.getPromptAction().closeCustomDialog(DialogUtils.contentNode)
  6. // 关闭一个弹窗就清空了,后面调用就都是null,所以关不掉
  7. DialogUtils.contentNode = null
  8. }
  9. }
  10. }

问题效果预览:

效果预览

背景知识

  • ComponentContent:表示组件内容的实体封装,其对象支持在非UI组件中创建与传递,便于开发者对弹窗类组件进行解耦封装。
  • @ohos.promptAction(弹窗):创建并显示文本提示框、对话框和操作菜单。
  • contentNode:ComponentContent创建的实例。

解决方案

弹窗关闭的代码有误,“DialogUtils.contentNode = null”关闭一个弹窗就清空了,后面调用就都是null,所以关不掉。

方案如下:用个数组存储每个弹窗的contentNode,每关闭一个pop()一个,并将数组最后一个值赋值给contentNode,关闭的就是上一个弹窗的contentNode。

完整示例参考如下:

  1. DialogUtils.ets。
    收起
    自动换行
    深色代码主题
    复制
    1. import { ComponentContent, promptAction } from '@kit.ArkUI';
    2. export class Params {
    3. content: string = '';
    4. callback: (isGranted: boolean, msg?: string) => void = (): void => {
    5. };
    6. constructor(content: string, callback: (isGranted: boolean, msg?: string) => void) {
    7. this.content = content;
    8. this.callback = callback;
    9. }
    10. }
    11. @Builder
    12. export function buildText(params: Params) {
    13. Column() {
    14. Column() {
    15. // 内容
    16. Text(params.content)
    17. .width('100%')
    18. .textAlign(TextAlign.Start)
    19. .padding(15)
    20. .fontSize(18)
    21. .fontColor('#2c2c2c')
    22. Column()
    23. .width('100%')
    24. .height(0.5)
    25. .backgroundColor('#E6E6E6')
    26. // 取消、确定按钮
    27. Row() {
    28. // 取消按钮
    29. Text('取消按钮')
    30. .width(0)
    31. .layoutWeight(1)
    32. .textAlign(TextAlign.Center)
    33. .padding({ top: 20, bottom: 20 })
    34. .fontColor('#BDBDBD')
    35. .borderRadius({ bottomLeft: 5 })
    36. .fontSize(15)
    37. .onClick(() => {
    38. DialogUtils.closeDialog();
    39. })
    40. Text('确定按钮')
    41. .width(0)
    42. .layoutWeight(1)
    43. .textAlign(TextAlign.Center)
    44. .padding({ top: 20, bottom: 20 })
    45. .fontColor('#BDBDBD')
    46. .borderRadius({ bottomLeft: 5 })
    47. .fontSize(15)
    48. .onClick(() => {
    49. DialogUtils.closeDialog();
    50. params.callback(false, 'okk');
    51. })
    52. }
    53. .width('100%')
    54. .alignItems(VerticalAlign.Center)
    55. .justifyContent(FlexAlign.SpaceAround)
    56. }
    57. .backgroundColor(Color.White)
    58. .borderRadius(5)
    59. .margin({ left: 15, right: 15 })
    60. }
    61. .height('100%')
    62. .width('100%')
    63. .justifyContent(FlexAlign.Center)
    64. .backgroundColor(Color.Transparent)
    65. }
    66. export default class DialogUtils {
    67. static contentNode: ComponentContent<Params> | null = null;
    68. static contentNodes: Array<ComponentContent<Params>> = [];
    69. static showDialog(content: string, callback: (isGranted: boolean, msg?: string) => void) {
    70. let uiContext: UIContext | undefined = AppStorage.get<UIContext>('uiContext');
    71. if (uiContext) {
    72. let promptAction = uiContext.getPromptAction();
    73. DialogUtils.contentNode = new ComponentContent(uiContext, wrapBuilder(buildText), new Params(content, callback));
    74. DialogUtils.contentNodes.push(DialogUtils.contentNode);
    75. let options: promptAction.BaseDialogOptions = {
    76. alignment: DialogAlignment.Top,
    77. autoCancel: false,
    78. maskColor: '#cd000000',
    79. };
    80. promptAction.openCustomDialog(DialogUtils.contentNode, options);
    81. }
    82. }
    83. public static closeDialog() {
    84. if (DialogUtils.contentNode) {
    85. let uiContext: UIContext | undefined = AppStorage.get<UIContext>('uiContext');
    86. if (uiContext) {
    87. let promptAction = uiContext.getPromptAction();
    88. promptAction.closeCustomDialog(DialogUtils.contentNode);
    89. if (DialogUtils.contentNodes.length > 0) {
    90. DialogUtils.contentNodes.pop();
    91. if (DialogUtils.contentNodes.length > 0) {
    92. DialogUtils.contentNode = DialogUtils.contentNodes[DialogUtils.contentNodes.length - 1];
    93. } else {
    94. DialogUtils.contentNode = null;
    95. }
    96. }
    97. }
    98. }
    99. }
    100. }
  2. Index.ets。
    收起
    自动换行
    深色代码主题
    复制
    1. import DialogUtils from './DialogUtils';
    2. AppStorage.setOrCreate('uiContext', undefined);
    3. @Entry
    4. @Component
    5. struct Index {
    6. pageInfos: NavPathStack = new NavPathStack();
    7. @StorageLink('uiContext') uiContext: UIContext | undefined = undefined;
    8. build() {
    9. Navigation(this.pageInfos) {
    10. RelativeContainer() {
    11. Text('首页')
    12. .fontSize(22)
    13. .alignRules({
    14. center: { anchor: '__container__', align: VerticalAlign.Center },
    15. middle: { anchor: '__container__', align: HorizontalAlign.Center }
    16. })
    17. }
    18. .width('100%')
    19. .height('100%')
    20. .backgroundColor(Color.White)
    21. }
    22. .hideTitleBar(false)
    23. .hideToolBar(false)
    24. }
    25. aboutToAppear(): void {
    26. this.uiContext = this.getUIContext();
    27. let nums: number = 8;
    28. for (let i = 0; i < nums; i++) {
    29. DialogUtils.showDialog(`hello world: ${i}`, (isGrant: boolean, msg?: string) => {
    30. console.log(`${isGrant}--------${msg}`);
    31. });
    32. }
    33. }
    34. }
在 FAQ 中进行搜索
请输入您想要搜索的关键词