DEV Community

victordeng
victordeng

Posted on

HarmonyOS NEXT project practice:use openCustomDialog

reference material:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-uicontext-custom-dialog

Due to various limitations in the use of the Customs Dialogue Controller, it does not support dynamic creation or refresh. In relatively complex application scenarios, it is recommended to use the openCustoms Dialog interface provided by the PromptAction object obtained from UIContext to implement custom pop ups.

The openCustoms dialog can be configured with isModal to achieve modal and non modal pop ups. When isModal is true, the pop-up box is a modal pop-up window. When isModal is false, the pop-up box is a non modal pop-up window.

life cycle
The pop-up box provides a lifecycle function to notify users of the lifecycle of the pop-up box. The triggering sequence of the lifecycle is: onWillAppeal ->onDiAppeal ->onWillDisappear ->onDiDisappear.

There are two ways to create custom pop ups for openCustoms dialog:

  • OpenCustoms Dialog (passed as Component Content): Encapsulating content through Component Content can decouple it from the UI interface, making calls more flexible and meeting the encapsulation needs of developers. It has high flexibility, with completely customizable pop-up box styles, and can dynamically update the parameters of the pop-up box using the updateCustoms Dialog method after it is opened.
  • OpenCustoms Dialog (in the form of a builder): Compared to Component Content, the builder must be bound to the context and have a certain coupling with the UI. This method uses a default pop-up style, which is suitable for developers who want to achieve the same effect as the default style of system pop ups. This article introduces the creation of custom pop ups for WidgetContent through parameter input, and the usage of pop ups in builder format can refer to openCustomizalDialog.

Implementation steps:

  1. Create WidgetContent. WidgetContent is used to define the content of custom pop ups. Among them, wrapBuilder (buildText) encapsulates custom components, and new Params (this. message) is the input parameter for custom components, which can be defaulted or passed in as the basic data type.
  2. Open the custom pop-up box. The pop-up box opened by calling the openCustomizalDialog interface defaults to a pop-up box with customStyle set to true, which means that the content style of the pop-up box is displayed completely according to the contentNode custom style.
  3. Close the custom pop-up box. Due to the need to pass in the Component Content corresponding to the pop-up box to be closed for the closeCustoms Dialog interface. Therefore, if you need to set a closing method in the pop-up box, you can refer to the complete example to encapsulate the static method for implementation. If you need to release the corresponding WidgetContent after closing the pop-up box, you need to call the dispose method of WidgetContent.

Example code:

import { BusinessError } from '@kit.BasicServicesKit';
import { ComponentContent, promptAction, UIContext } from '@kit.ArkUI';


@Entry
@Component
struct OpenCustomDialogPage {
  build() {
    Column({ space: 10 }) {
      Text('OpenCustomDialogPage')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      Button('open dialog').onClick(() => {
        Dialog.setContext(this.getUIContext());
        Dialog.setOptions({ alignment: DialogAlignment.Center });
        let contentNode: ComponentContent<Object> =
          new ComponentContent(this.getUIContext(), wrapBuilder(buildText), new Params('hello, you open a dialog'));
        Dialog.setContentNode(contentNode);
        Dialog.openDialog()
      })
    }
    .height('100%')
    .width('100%')
  }
}

@Builder
function buildText(params: Params) {
  Column() {
    Text(params.text)
      .fontSize(30)
      .fontWeight(FontWeight.Bold)
      .margin({ bottom: 36 })
    Button('Close')
      .onClick(() => {
        Dialog.closeDialog();
      })
  }
  .backgroundColor('#FFF0F0F0')
  .padding(20)
  .borderRadius(8)
  .clip(true)
  .margin(20)
}

class Dialog {
  static ctx: UIContext;
  static contentNode: ComponentContent<Object>;
  static options: promptAction.BaseDialogOptions;

  static setContext(context: UIContext) {
    Dialog.ctx = context;
  }

  static setContentNode(node: ComponentContent<Object>) {
    Dialog.contentNode = node;
  }

  static setOptions(options: promptAction.BaseDialogOptions) {
    Dialog.options = options;
  }

  static openDialog() {
    if (Dialog.contentNode !== null) {
      Dialog.ctx.getPromptAction()
        .openCustomDialog(Dialog.contentNode, Dialog.options)
        .then(() => {
          console.info('OpenCustomDialog complete.');
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`OpenCustomDialog args error code is ${code}, message is ${message}`);
        })
    }
  }

  static updateDialog(options: promptAction.BaseDialogOptions) {
    if (Dialog.contentNode !== null) {
      Dialog.ctx.getPromptAction().updateCustomDialog(Dialog.contentNode, options)
        .then(() => {
          console.info('UpdateCustomDialog complete.');
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`UpdateCustomDialog args error code is ${code}, message is ${message}`);
        })
    }
  }

  static closeDialog() {
    if (Dialog.contentNode !== null) {
      Dialog.ctx.getPromptAction()
        .closeCustomDialog(Dialog.contentNode)
        .then(() => {
          console.info('CloseCustomDialog complete.');
        })
        .catch((error: BusinessError) => {
          let message = (error as BusinessError).message;
          let code = (error as BusinessError).code;
          console.error(`CloseCustomDialog args error code is ${code}, message is ${message}`);
        })
    }
  }
}

class Params {
  text: string = "";

  constructor(text: string) {
    this.text = text;
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)