DEV Community

HarmonyOS
HarmonyOS

Posted on

How to encapsulate and invoke custom pop-up windows

Read the original article:How to encapsulate and invoke custom pop-up windows

Problem Description

If a page needs to display a custom dialog, the CustomDialogController must be defined for the page.

  1. If there are multiple pages, the CustomDialogController code will be defined repeatedly on each page.
  2. When multiple custom dialogs need to be defined on one page, multiple CustomDialogController definition code copies are generated.
  3. The same custom dialog is used on multiple pages, and CustomDialogController needs to be defined for each page, causing a large amount of code repetition.

kbs--5bd9d01de04b46739640c99049408bc8-274cd.png

In summary, the repeated definition of CustomDialogController code affects developers' efficiency and the cleanliness of the code.
Preview:

kbs--b5ec08255585424fa7a090ad4628cc6f-40bd37.gif

Background Knowledge

The CustomDialogController class is used to display a custom dialog box. When using the dialog box component, you are advised to use a custom dialog box to customize the dialog box style and content. For details, please refer to CustomDialog (CustomDialog).

Solution

You can encapsulate the custom dialog module so that you do not need to define CustomDialogController on each page. You only need to pass the following two parameters and call the method to obtain the custom dialog:

  • Transfer the pop-up window name.;
  • Customized content of the pop-up window, such as text or image.

The following is a code example, in which the testPromptDialog method is invoked:

// Encapsulate the method for displaying a pop-up, and pass the page name and text content to the method.
export function testPromptDialog(pageName: string, text: string, controller: Function) {
  let that = GlobalContext.getGlobalContext().getObject(pageName) as UIContext;
  let context = GlobalContext.getGlobalContext().getObject('UIContext') as UIContext;
  if (that) {
    context.getPromptAction().openCustomDialog({
      builder: controller.bind(that, text)
    }).then((dialogId: number) => {
      customDialogId = dialogId;
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

The development procedure is as follows:

1.The GlobalContext.ets tool class is created to save and obtain the context of a page.

export class GlobalContext {
  private constructor() {
  }
  // Defines the GlobalContext for global calls.
  private static instance: GlobalContext;
  private _objects = new Map<string, Object>();
  // Singleton method of GlobalContext
  public static getGlobalContext(): GlobalContext {
    if (!GlobalContext.instance) {
      GlobalContext.instance = new GlobalContext();
    }
    return GlobalContext.instance;
  }
  // Value Range
  getObject(value: string): Object | undefined {
    return this._objects.get(value);
  }
  // Deposit value
  setObject(key: string, objectClass: Object): void {
    this._objects.set(key, objectClass);
  }
}
Enter fullscreen mode Exit fullscreen mode

2.The DialogUtils.ets tool class is created, which encapsulates a custom dialog and the method for displaying the custom dialog. The custom dialog is displayed by calling this.getUIContext().getPromptAction().openCustomDialog.

import { GlobalContext } from './GlobalContext';

let customDialogId: number = 0;
// Defines the failure builder.
@Builder
export function failDialogBuilder(content: String) {
  Column() {
    Text(content as string)
      .fontSize(20).height('30%');
    Text('Failure cause:' + content).fontSize(16).height('30%');
    Row() {
      Button('Confirming the operation.').onClick(() => {
        let that = GlobalContext.getGlobalContext().getObject('UIContext') as UIContext;
        if (that) {
          that.getPromptAction().closeCustomDialog(customDialogId);
        }
      });
      Blank().width(50);
      Button('Cancel').onClick(() => {
        let that = GlobalContext.getGlobalContext().getObject('UIContext') as UIContext;
        if (that) {
          that.getPromptAction().closeCustomDialog(customDialogId);
        }
      });
    }
    .margin({ top: 30 });
  }.height(200).padding(5);
}
// Define a successful builder
@Builder
export function successDialogBuilder(content: String) {
  Column() {
    Text(content as string)
      .fontSize(20).height('30%');
    Text('Success reasons:' + content).fontSize(16).height('30%');
    Row() {
      Button('Confirming the operation.').onClick(() => {
        let that = GlobalContext.getGlobalContext().getObject('UIContext') as UIContext;
        if (that) {
          that.getPromptAction().closeCustomDialog(customDialogId);
        }
      });
      Blank().width(50);
      Button('Cancel').onClick(() => {
        let that = GlobalContext.getGlobalContext().getObject('UIContext') as UIContext;
        if (that) {
          that.getPromptAction().closeCustomDialog(customDialogId);
        }
      });
    }
    .margin({ top: 30 });
  }.height(200).padding(5);
}
// Encapsulate the method for displaying a pop-up, and pass the page name and text content to the method.
export function testPromptDialog(pageName: string, text: string, controller: Function) {
  let that = GlobalContext.getGlobalContext().getObject(pageName) as UIContext;
  let context = GlobalContext.getGlobalContext().getObject('UIContext') as UIContext;
  if (that) {
    context.getPromptAction().openCustomDialog({
      builder: controller.bind(that, text)
    }).then((dialogId: number) => {
      customDialogId = dialogId;
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

3.The context is stored during page initialization, and then the customized dialog encapsulation method is called at the entry.

import { GlobalContext } from './GlobalContext';
import { failDialogBuilder, successDialogBuilder, testPromptDialog } from './DialogUtils';

@Entry
@Component
struct Index {
  aboutToAppear(): void {
    // Sets the context of a page.
    GlobalContext.getGlobalContext().setObject('pageName', this);
    GlobalContext.getGlobalContext().setObject('UIContext', this.getUIContext());
  }

  build() {
    Row() {
      Column() {
        Button('PromptAction failure pop-up window.')
          .onClick(() => {
            testPromptDialog('pageName', 'this is  dialog1', failDialogBuilder);
          });
        Button('Successful promptAction pop-up window.')
          .margin({ top: 15 })
          .onClick(() => {
            testPromptDialog('pageName', 'this is dialog2', successDialogBuilder);
          });
      }
      .width('100%');
    }
    .height('100%');
  }
}
Enter fullscreen mode Exit fullscreen mode

Verification Result

During development, if you encounter code for utility classes that need to be defined repeatedly, you can encapsulate these utility classes and use GlobalContext to record the page context. You can then obtain the desired functions, such as pop-up windows, by encapsulating methods and passing parameters.

This sample tested on API version 20.
This sample tested on HarmonyOS 6.0.0 Release.

Written by Emrecan Karakas

Top comments (0)