HarmonyOS鸿蒙Next中OpenCustomDialog实现

HarmonyOS鸿蒙Next中OpenCustomDialog实现 自定义弹窗组件

在进行自定义弹窗组件开发时如果要实现内容、标题、按钮内容等都要实现一套代码传参自定义改变内容时可以选择此方案

  1. 首先引入相关依赖/环境/模块
import { BusinessError } from '@kit.BasicServicesKit';
import { ComponentContent, PromptAction, promptAction } from '@kit.ArkUI';
  1. 定义变量
let contentNode: ComponentContent<Params>;
let noUiContext: UIContext;
  • contentNode:用于存储弹窗的内容节点,类型是ComponentContent<Params>,其中Params是自定义的参数类型。
  • noUiContext:用于存储UI上下文对象,类型是UIContext,它可能是用来操作UI的上下文环境。
  1. 定义参数
class Params {
  title?: string = "";
  message: string = '';
  button1: string = "";
  button2: string = "";
  onOkClick?: () => void;
  onCaleClick?: () => void;

  constructor(
    message: string,
    button1: string,
    button2: string,
    onOkClick?: () => void,
    onCaleClick?: () => void,
    title?: string
  ) {
    this.title = title;
    this.message = message;
    this.button1 = button1;
    this.button2 = button2;
    this.onOkClick = onOkClick;
    this.onCaleClick = onCaleClick;
  }
}
  • Params是一个参数类,用于封装弹窗需要的参数:
    • title:弹窗标题(可选)。
    • message:弹窗的主要消息内容。
    • button1button2:弹窗中的两个按钮的文本。
    • onOkClickonCaleClick:按钮点击事件的回调函数。
    • 构造函数允许在创建Params实例时直接传入这些参数。
  1. 构建弹窗内容
@Builder
function buildText(params: Params) {
  Column() {
    if (params.title && params.title.length > 0) {
      Text(params.title)
        .width('100%')
        .fontSize(15)
        .fontWeight(700)
        .fontColor('#333333')
        .textAlign(TextAlign.Center)
        .padding({ left: 25, right: 25 })
        .margin({ top: 20 });
    }
    Text(params.message)
      .width('100%')
      .fontSize(16)
      .textAlign(TextAlign.Center)
      .margin({ bottom: 36 })
      .padding({
        left: 15,
        right: 15,
        top: 25,
        bottom: 15
      })
      .border({
        color: Color.Gray,
        width: {
          bottom: 1
        }
      });
    Flex({ justifyContent: FlexAlign.SpaceAround }) {
      Text(params.button1)
        .fontSize(16)
        .textAlign(TextAlign.Center)
        .fontColor('#333333')
        .border({
          color: Color.Gray,
          width: {
            right: 1
          },
          style: BorderStyle.Solid
        })
        .padding({ right: 60 })
        .onClick(() => {
          const promptAction: PromptAction = noUiContext.getPromptAction();
          promptAction.closeCustomDialog(contentNode);
        });
      Text(params.button2)
        .onClick(() => {
          const promptAction: PromptAction = noUiContext.getPromptAction();
          promptAction.closeCustomDialog(contentNode);
          params.onOkClick && params.onOkClick();
        })
        .fontSize(16)
        .textAlign(TextAlign.Center)
        .fontColor("#0022AB");
    }.margin({ top: -30 })
      .padding({
        left: 15,
        right: 15,
        top: 25,
        bottom: 15
      });
  }.backgroundColor('#FFF0F0F0')
    .borderRadius(12)
    .border({
      color: "#EEEEEE",
      width: {
        left: 1
      }
    })
    .width(280)
    .opacity(1);
}
  1. 显示弹窗函数
export function DialogName(
  uiContext: UIContext,
  message: string,
  button1: string,
  button2?: string,
  onOkClick?: () => void,
  onCaleClick?: () => void,
  title?: string
) {
  noUiContext = uiContext;
  let promptAction = uiContext.getPromptAction();
  contentNode = new ComponentContent(
    uiContext,
    wrapBuilder(buildText),
    new Params(message, button1, button2 as string, onOkClick, onCaleClick, title)
  );
  try {
    promptAction.openCustomDialog(contentNode);
  } catch (error) {
    // 空的catch块,可能用于忽略错误
  }
}

DialogName是一个函数,用于显示弹窗:

  • 参数:
    • uiContext:UI上下文对象。
    • message:弹窗消息内容。
    • button1button2:按钮文本。
    • onOkClickonCaleClick:按钮点击事件的回调函数。
    • title:弹窗标题(可选)。
  • 逻辑:
    • 将传入的uiContext赋值给noUiContext
    • 获取PromptAction对象,用于管理弹窗。
    • 创建contentNode,将buildText函数包装为一个组件内容,并传入Params实例。
    • 调用openCustomDialog方法显示弹窗。
  1. 组件定义 ConfirmDialog
[@Component](/user/Component)
export struct ConfirmDialog {
  build() {
    Column() {}
  }
}
  1. 完整代码/案例
import { BusinessError } from '@kit.BasicServicesKit';
import { ComponentContent, PromptAction, promptAction } from '@kit.ArkUI';

let contentNode: ComponentContent<Params>;
let noUiContext: UIContext;

class Params {
  title?: string = "";
  message: string = '';
  button1: string = "";
  button2: string = "";
  onOkClick?: () => void;
  onCaleClick?: () => void;

  constructor(
    message: string,
    button1: string,
    button2: string,
    onOkClick?: () => void,
    onCaleClick?: () => void,
    title?: string
  ) {
    this.title = title;
    this.message = message;
    this.button1 = button1;
    this.button2 = button2;
    this.onOkClick = onOkClick;
    this.onCaleClick = onCaleClick;
  }
}

@Builder
function buildText(params: Params) {
  Column() {
    if (params.title && params.title.length > 0) {
      Text(params.title)
        .width('100%')
        .fontSize(15)
        .fontWeight(700)
        .fontColor('#333333')
        .textAlign(TextAlign.Center)
        .padding({ left: 25, right: 25 })
        .margin({ top: 20 });
    }
    Text(params.message)
      .width('100%')
      .fontSize(16)
      .textAlign(TextAlign.Center)
      .margin({ bottom: 36 })
      .padding({
        left: 15,
        right: 15,
        top: 25,
        bottom: 15
      })
      .border({
        color: Color.Gray,
        width: {
          bottom: 1
        }
      });
    Flex({ justifyContent: FlexAlign.SpaceAround }) {
      Text(params.button1)
        .fontSize(16)
        .textAlign(TextAlign.Center)
        .fontColor('#33333')
        .border({
          color: Color.Gray,
          width: {
            right: 1
          },
          style: BorderStyle.Solid
        })
        .padding({ right: 60 })
        .onClick(() => {
          const promptAction: PromptAction = noUiContext.getPromptAction();
          promptAction.closeCustomDialog(contentNode);
        });
      Text(params.button2)
        .onClick(() => {
          const promptAction: PromptAction = noUiContext.getPromptAction();
          promptAction.closeCustomDialog(contentNode);
          params.onOkClick && params.onOkClick();
        })
        .fontSize(16)
        .textAlign(TextAlign.Center)
        .fontColor("#0022AB");
    }.margin({ top: -30 })
      .padding({
        left: 15,
        right: 15,
        top: 25,
        bottom: 15
      });
  }.backgroundColor('#FFF0F0F0')
    .borderRadius(12)
    .border({
      color: "#EEEEEE",
      width: {
        left: 1
      }
    })
    .width(280)
    .opacity(1);
}

export function DialogName(
  uiContext: UIContext,
  message: string,
  button1: string,
  button2?: string,
  onOkClick?: () => void,
  onCaleClick?: () => void,
  title?: string
) {
  noUiContext = uiContext;
  let promptAction = uiContext.getPromptAction();
  contentNode = new ComponentContent(
    uiContext,
    wrapBuilder(buildText),
    new Params(message, button1, button2 as string, onOkClick, onCaleClick, title)
  );
  try {
    promptAction.openCustomDialog(contentNode);
  } catch (error) {
    // 空的catch块,可能用于忽略错误
  }
}

@Component export struct ConfirmDialog { build() { Column() {} } }


更多关于HarmonyOS鸿蒙Next中OpenCustomDialog实现的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS(鸿蒙)Next中,OpenCustomDialog的实现通常涉及使用ArkUI框架中的自定义弹窗组件。ArkUI是鸿蒙系统提供的声明式UI开发框架,支持使用TypeScript或JavaScript进行开发。

要实现一个自定义弹窗,可以按照以下步骤进行:

  1. 定义弹窗内容:首先,定义一个自定义弹窗的UI布局。这个布局可以使用ArkUI提供的组件,如TextButtonImage等。

  2. 创建自定义弹窗组件:使用@CustomDialog装饰器来定义一个自定义弹窗组件。这个组件需要继承自CustomDialogController,并在其中实现弹窗的显示和隐藏逻辑。

  3. 绑定数据和事件:在自定义弹窗组件中,可以通过@State@Prop等装饰器来绑定数据,并通过事件回调来处理用户交互。

  4. 显示弹窗:在需要使用弹窗的地方,通过调用CustomDialogControlleropen方法来显示弹窗。

以下是一个简单的代码示例,展示了如何实现一个自定义弹窗:

@CustomDialog
export struct MyCustomDialog {
  @State message: string = 'Hello, Custom Dialog!'

  build() {
    Column() {
      Text(this.message)
        .fontSize(20)
        .margin({ bottom: 20 })

      Button('Close')
        .onClick(() => {
          // 关闭弹窗
          this.controller.close()
        })
    }
    .padding(20)
  }
}

@Entry
@Component
struct MyPage {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: MyCustomDialog(),
    cancel: () => {
      console.log('Dialog closed')
    }
  })

  build() {
    Column() {
      Button('Open Dialog')
        .onClick(() => {
          // 显示弹窗
          this.dialogController.open()
        })
    }
  }
}

在这个示例中,MyCustomDialog是一个自定义弹窗组件,MyPage是页面组件。当用户点击“Open Dialog”按钮时,弹窗会显示出来,点击“Close”按钮则会关闭弹窗。

通过这种方式,你可以在HarmonyOS Next中实现自定义弹窗,并根据需要调整弹窗的内容和交互逻辑。

更多关于HarmonyOS鸿蒙Next中OpenCustomDialog实现的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,OpenCustomDialog 用于打开自定义对话框。你可以通过以下步骤实现:

  1. 创建自定义布局:在 resources/base/layout 目录下创建 XML 布局文件,定义对话框内容。

  2. 实现对话框逻辑:在代码中继承 CommonDialogBaseDialog,并重写 onCreateView 方法,加载自定义布局。

  3. 打开对话框:在需要的地方实例化自定义对话框并调用 show() 方法。

示例代码如下:

public class CustomDialog extends CommonDialog {
    @Override
    protected Component onCreateView(ComponentContainer parent) {
        LayoutScatter scatter = LayoutScatter.getInstance(getContext());
        return scatter.parse(ResourceTable.Layout_custom_dialog, parent, false);
    }
}

// 打开对话框
CustomDialog dialog = new CustomDialog();
dialog.show();

确保在布局文件中定义 custom_dialog.xml,并在 show() 方法前设置对话框属性(如大小、位置等)。

回到顶部