HarmonyOS鸿蒙Next中如何进行自定义弹窗的封装调用

HarmonyOS鸿蒙Next中如何进行自定义弹窗的封装调用

【问题现象】

如果一个页面需要弹出自定义弹窗,那么页面就需要定义CustomDialogController。

  1. 多个页面就会出现多份重复的定义CustomDialogController代码。
  2. 一个页面需要定义多个自定义弹窗时,会出现多份重复的CustomDialogController定义代码。
  3. 相同的自定义弹窗在多个页面使用,每个页面都需要去定义CustomDialogController,造成大量代码的重复。

点击放大

综上,重复的定义CustomDialogController代码会影响开发者的开发效率以及代码的整洁。

【背景知识】

HarmonyOS自定义弹窗

【解决方案】

可以通过封装自定义弹窗模块,这样就无需在每个页面定义CustomDialogController,仅需传入以下两个参数,调用方法即可获得自定义弹窗:

  • 传入弹窗名称;
  • 传入弹窗自定义内容,如文本内容,图片内容。

代码示例如下,调用的是testPromptDialog方法:

// 传入页面名称和文本内容
export function testPromptDialog(pageName: string, text: string) {
  const that = GlobalContext.getContext().getObject(pageName) as UIContext;
  if (that) {
    promptAction.openCustomDialog({
      builder: customDialogBuilder.bind(that, text)
    }).then((dialogId: number) => {
      customDialogId = dialogId;
    })
  }
}

效果如下:

点击放大

点击放大

开发步骤如下:

  1. 新建GlobalContext.ets工具类,用于页面context的保存和获取。
export class GlobalContext {
  private constructor() {
  }

  private static instance: GlobalContext;
  private _objects = new Map<string, Object>();

  public static getContext(): GlobalContext {
    if (!GlobalContext.instance) {
      GlobalContext.instance = new GlobalContext();
    }
    return GlobalContext.instance;
  }

  getObject(value: string): Object | undefined {
    return this._objects.get(value);
  }

  setObject(key: string, objectClass: Object): void {
    this._objects.set(key, objectClass);
  }
}
  1. 新建DialogUtils.ets工具类,工具类中已封装了自定义弹窗,以及弹出自定义弹窗的方法。拉起弹窗通过promptAction.openCustomDialog来实现。
import { promptAction } from '@kit.ArkUI'
import { GlobalContext } from './GlobalContext'

let customDialogId: number = 0

@Builder
export function customDialogBuilder(content: String) {
  Column() {
    Text(`Tip:${content}`)
    .fontSize(20).height("30%")
    Text(`失败原因:${content}`).fontSize(16).height("30%")
    Row() {
      Button("确认").onClick(() => {
        promptAction.closeCustomDialog(customDialogId)
      })
      Blank().width(50)
      Button("取消").onClick(() => {
        promptAction.closeCustomDialog(customDialogId)
      })
    }
    .margin({ top: 30 })
  }.height(200).padding(5)
}

// 传入页面名称和文本内容
export function testPromptDialog(pageName: string, text: string) {
  const that = GlobalContext.getContext().getObject(pageName) as UIContext;
  if (that) {
    promptAction.openCustomDialog({
      builder: customDialogBuilder.bind(that, text)
    }).then((dialogId: number) => {
      customDialogId = dialogId;
    })
  }
}
  1. 页面初始化时存入context, 然后在入口处调用 自定义弹窗封装方法。
import { GlobalContext } from '../utils/GlobalContext'
import { testPromptDialog } from '../utils/DialogUtils'

@Entry
@Component
struct Index {
  aboutToAppear(): void {
    // 设置page的Context
    GlobalContext.getContext().setObject('pageName', this)
  }

  build() {
    Row() {
      Column() {
        Button("promptAction弹窗")
          .onClick(() => {
            testPromptDialog("pageName", "this is a dialog")
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

【总结】

在开发中,遇到需要重复定义的工具类代码,可以封装工具类,并使用GlobalContext去记录页面Context,通过封装方法并传入参数的方式获得想要的弹窗等功能。


更多关于HarmonyOS鸿蒙Next中如何进行自定义弹窗的封装调用的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中如何进行自定义弹窗的封装调用的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,可以通过封装自定义弹窗模块来避免重复定义CustomDialogController。具体步骤如下:

  1. 新建GlobalContext.ets工具类,用于保存和获取页面Context。
  2. 新建DialogUtils.ets工具类,封装自定义弹窗及弹窗方法,使用promptAction.openCustomDialog拉起弹窗。
  3. 在页面初始化时存入Context,并在入口处调用封装的自定义弹窗方法。

示例代码:

// GlobalContext.ets
export class GlobalContext {
  private static instance: GlobalContext;
  private _objects = new Map<string, Object>();

  public static getContext(): GlobalContext {
    if (!GlobalContext.instance) {
      GlobalContext.instance = new GlobalContext();
    }
    return GlobalContext.instance;
  }

  getObject(value: string): Object | undefined {
    return this._objects.get(value);
  }

  setObject(key: string, objectClass: Object): void {
    this._objects.set(key, objectClass);
  }
}

// DialogUtils.ets
import { promptAction } from '@kit.ArkUI';
import { GlobalContext } from './GlobalContext';

let customDialogId: number = 0;

@Builder
export function customDialogBuilder(content: String) {
  Column() {
    Text(`Tip:${content}`).fontSize(20).height("30%")
    Text(`失败原因:${content}`).fontSize(16).height("30%")
    Row() {
      Button("确认").onClick(() => {
        promptAction.closeCustomDialog(customDialogId)
      })
      Blank().width(50)
      Button("取消").onClick(() => {
        promptAction.closeCustomDialog(customDialogId)
      })
    }.margin({ top: 30 })
  }.height(200).padding(5)
}

export function testPromptDialog(pageName: string, text: string) {
  const that = GlobalContext.getContext().getObject(pageName) as UIContext;
  if (that) {
    promptAction.openCustomDialog({
      builder: customDialogBuilder.bind(that, text)
    }).then((dialogId: number) => {
      customDialogId = dialogId;
    })
  }
}

// 页面调用
import { GlobalContext } from '../utils/GlobalContext';
import { testPromptDialog } from '../utils/DialogUtils';

@Entry
@Component
struct Index {
  aboutToAppear(): void {
    GlobalContext.getContext().setObject('pageName', this)
  }

  build() {
    Row() {
      Column() {
        Button("promptAction弹窗").onClick(() => {
          testPromptDialog("pageName", "this is a dialog")
        })
      }.width('100%')
    }.height('100%')
  }
}

通过封装工具类,可以减少代码重复,提高开发效率。

回到顶部