DEV Community

刘年华
刘年华

Posted on

How to Call Global Dialogs from Classes in HarmonyOS

Introduction

I'm sure many of you have been using @CustomDialog for custom dialogs in your development, writing a bunch of initialization code on each page, and finding it particularly difficult to call from within classes. Today, I'd like to share how to use promptAction.openCustomDialog to call global dialogs from within classes in HarmonyOS.

Implementation Guide

Step 1: Store the Context in EntryAbility (Required)

Image description

onWindowStageCreate(windowStage: window.WindowStage): void {
  windowStage.loadContent('pages/Index', (err) => {
    window.getLastWindow(this.context).then((data: window.Window) => {
      let uiContext = data.getUIContext();
      AppStorage.setOrCreate<UIContext>('UIContext', uiContext);
    });
  });
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a Builder (Customize the Style)

Image description

export class Params {
  text: ResourceStr = ""

  constructor(text: ResourceStr) {
    this.text = text;
  }
}

@Builder
export function testTextBuilder(params: Params) {
  Column() {
    Text(params.text)
      .textAlign(TextAlign.Center)
      .fontSize(20)
      .borderRadius(6)
      .backgroundColor('rgba(24, 25, 26, 0.85)')
      .fontColor($r('sys.color.comp_background_list_card'))
      .padding(16)
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Define a Global Class

Image description

export class DialogModel {
  static showDialog(message: string) {
    if (message != '') {
      let timeId: number = -1
      // Get the context
      let uiContext = AppStorage.get('UIContext') as UIContext
      let promptAction = uiContext.getPromptAction();
      let contentNode = new ComponentContent(uiContext, wrapBuilder(testTextBuilder), new Params(message));
      promptAction.openCustomDialog(contentNode, {
        isModal: false,
        onWillAppear: () => {
          timeId = setTimeout(() => {
            promptAction.closeCustomDialog(contentNode)
          }, 2000)
        },
        onDidDisappear: () => {
          clearTimeout(timeId)
        },
        keyboardAvoidMode: KeyboardAvoidMode.NONE,
        showInSubWindow: true,
      })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Implementation

@Entry
@Component
struct Index {
  build() {
    Column() {
      Button('Click me for a dialog')
        .onClick(() => {
          DialogModel.showDialog('Here it is!')
        })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Result

Image description

Limitations

  1. The dialog closes when navigating back (not an issue for toast notifications)
  2. Continuous clicks will keep showing dialogs (some requirements may need to close the previous dialog when opening a new one)
  3. You might want to exit the page stack without closing the dialog

Top comments (0)