【鸿蒙 NEXT】自定义dialog

MyAlertDialog

typescript 复制代码
export interface MyAlertDialogConfig {
  onClickButton?: (index: number) => void
  title?: string
  message?: string
}


@CustomDialog
export struct MyAlertDialog {
  controller?: CustomDialogController
  onClickButton: (index: number) => void = (index: number) => {
  }
  @State title: string = ''
  @State message: string = ''

  build() {
    Column() {
      Text(this.title)
        .fontColor(Color.Black)
        .fontSize(18)
        .textAlign(TextAlign.Center)
        .fontWeight(FontWeight.Bold)
        .width('100%')
        .margin({ top: 16, bottom: 16 })
      // Divider().width('100%').height(1).backgroundColor($r('app.color.line_color'))
      TextArea({ text: this.message })
        .textAlign(TextAlign.Center)
        .width(430)
        .maxLength(150)
        .enabled(false)
        .padding(16)
        .fontColor(Color.Black)
        .backgroundColor(Color.White)
      Blank().height(20)
      Divider().width('100%').height(1).backgroundColor('#E5E5E5')
      Row() {
        Button('取消')
          .size({ width: '50%', height: 45 })
          .backgroundColor(Color.White)
          .fontColor(Color.Black)
          .type(ButtonType.Normal)
          .borderRadius({ bottomLeft: 15 })
          .onClick(() => {
            this.onClickButton(0)
          })
        Button('确定')
          .size({ width: '50%', height: 45 })
          .backgroundColor('#5565F5')
          .fontColor(Color.White)
          .type(ButtonType.Normal)
          .borderRadius({ bottomRight: 15 })
          .onClick(() => {
            this.onClickButton(1)
          })
      }
    }
    .width(430)
    .borderRadius(15)
    .padding(0)
    .backgroundColor(Color.White)
    .borderWidth(1)
    .borderColor('#E5E5E5')
    .shadow(ShadowStyle.OUTER_DEFAULT_XS)
  }
}

DialogUtil

typescript 复制代码
import { MyAlertDialog, MyAlertDialogConfig } from './dialog/MyAlertDialog'
import { PopupBuilder } from './pop/PopupBuilder'


export class DialogUtil {
  public static createAlertDialog(config?: MyAlertDialogConfig) {
    let dialog = new PopupBuilder()
      .setModal(true)
      .setDismissOnTouchOutside(false)
      .setMaskColor(Color.Transparent)
      .asCustom(wrapBuilder(builderAlertDialog), config)
    return dialog
  }
}

@Builder
function builderAlertDialog(config?: MyAlertDialogConfig) {
  MyAlertDialog({ onClickButton: config?.onClickButton, title: config?.title, message: config?.message })
}

PopupBuilder

typescript 复制代码
import { promptAction } from '@kit.ArkUI'
import { PopupManager } from './PopupManager'

export class PopupBuilder {
  /**
   * 自定义Builder
   */
  private customBuilder?: WrappedBuilder<ESObject>
  /**
   * 弹窗默认配置
   */
  private dialogOptions: promptAction.BaseDialogOptions = {}
  /**
   * 参数
   */
  private args?: ESObject
  /**
   * 弹窗管理
   */
  private popupManager?: PopupManager

  /**
   * 是否可通过物理返回关闭
   */
  private backPressDismiss: boolean = false

  /**
   * 设置窗口配置
   * @param dialogOptions 设置配置
   * @returns
   */
  setDialogOptions(dialogOptions: promptAction.BaseDialogOptions): PopupBuilder {
    this.dialogOptions = dialogOptions
    return this
  }

  /**
   * 屏蔽对话框区域。大小不能超过主窗口
   * @param maskRect
   * @returns
   */
  setMaskRect(maskRect?: Rectangle): PopupBuilder {
    this.dialogOptions.maskRect = maskRect
    return this
  }

  /**
   * 系统键盘避让模式
   * @param mode
   * @returns
   */
  setKeyboardAvoidMode(mode: KeyboardAvoidMode): PopupBuilder {
    this.dialogOptions.keyboardAvoidMode = mode
    return this
  }

  /**
   * 设置对话框的对齐方式
   * @param alignment
   * @returns
   */
  setAlignment(alignment?: DialogAlignment): PopupBuilder {
    this.dialogOptions.alignment = alignment
    return this
  }

  /**
   * 对话框偏移量
   * @param offset
   * @returns
   */
  setOffset(offset?: Offset): PopupBuilder {
    this.dialogOptions.offset = offset
    return this
  }

  /**
   * 是否在子窗口中显示
   * @param showInSubWindow
   * @returns
   */
  setInSubWindow(showInSubWindow: boolean): PopupBuilder {
    this.dialogOptions.showInSubWindow = showInSubWindow
    return this
  }

  /**
   * 模态对话框
   * @param isModal
   * @returns
   */
  setModal(isModal: boolean): PopupBuilder {
    this.dialogOptions.isModal = isModal
    return this
  }

  /**
   * 允许用户单击遮罩层退出
   * @param dismiss
   * @returns
   */
  setDismissOnTouchOutside(dismiss: boolean): PopupBuilder {
    this.dialogOptions.autoCancel = dismiss
    return this
  }

  /**
   * 设置是否支持按返回键关闭弹窗
   * @param dismiss
   * @returns
   */
  setDismissOnBackPressed(dismiss: boolean): PopupBuilder {
    this.backPressDismiss = dismiss
    return this
  }

  /**
   * 打开/关闭自定义对话框的转换参数
   * @param transition
   * @returns
   */
  setTransition(transition?: TransitionEffect): PopupBuilder {
    this.dialogOptions.transition = transition
    return this
  }

  /**
   * 设置遮罩层颜色
   * @param maskColor
   * @returns
   */
  setMaskColor(maskColor?: ResourceColor): PopupBuilder {
    this.dialogOptions.maskColor = maskColor
    return this
  }

  /**
   * 弹窗即将消失回调,可拦截关闭
   * @param onWillDismiss
   * @returns
   */
  setOnWillDismiss(onWillDismiss?: Callback<DismissDialogAction>): PopupBuilder {
    this.dialogOptions.onWillDismiss = onWillDismiss
    return this
  }

  /**
   * 对话框出现时的回调功能
   * @param onDidAppear
   * @returns
   */
  setOnDidAppear(onDidAppear?: () => void): PopupBuilder {
    this.dialogOptions.onDidAppear = onDidAppear
    return this
  }

  /**
   * 对话框消失时的回调功能
   * @param onDidAppear
   * @returns
   */
  setOnDidDisappear(onDidDisappear?: () => void): PopupBuilder {
    this.dialogOptions.onDidDisappear = onDidDisappear
    return this
  }

  /**
   * 弹窗即将打开前回调
   * @param onWillAppear
   * @returns
   */
  setOnWillAppear(onWillAppear?: () => void): PopupBuilder {
    this.dialogOptions.onWillAppear = onWillAppear
    return this
  }

  /**
   * 弹窗即将关闭回调
   * @param onWillDisappear
   * @returns
   */
  setOnWillDisappear(onWillDisappear?: () => void): PopupBuilder {
    this.dialogOptions.onWillDisappear = onWillDisappear
    return this
  }

  /**
   * 自定义视图
   * @returns
   */
  asCustom<T extends object>(customBuilder: WrappedBuilder<T[]>, args?: T | undefined): PopupBuilder {
    this.customBuilder = customBuilder
    this.args = args
    return this
  }

  /**
   * 显示弹窗
   */
  async show() {
    if (this.customBuilder) {
      //处理关闭
      if (this.dialogOptions.onWillDismiss == null) {
        this.dialogOptions.onWillDismiss = this._onWillDismiss
      }
      this.popupManager = new PopupManager()
      await this.popupManager.show(this.dialogOptions, this.customBuilder, this.args)
    }
  }

  /**
   * 关闭弹窗
   */
  async dismiss() {
    if (this.popupManager) {
      await this.popupManager.dismiss()
    }
  }

  /**
   * 处理即将关闭
   */
  private _onWillDismiss = (data: DismissDialogAction) => {
    if (data.reason == DismissReason.PRESS_BACK && !this.backPressDismiss) {
      //禁止关闭
    } else {
      data.dismiss()
    }
  }
}

PopupManager

typescript 复制代码
import { ComponentContent, promptAction, PromptAction, window } from '@kit.ArkUI';

export class PopupManager{
  private popup?: ComponentContent<object>
  private promptAction?: PromptAction

  /**
   * 显示
   * @param hint
   */
  async show<T extends object>(config: promptAction.BaseDialogOptions, wrapBuilder: WrappedBuilder<T[]>, args?: T) {
    try {
      const windowClass = await window.getLastWindow(getContext())
      const uiContext = windowClass.getUIContext()
      if (args) {
        this.popup = new ComponentContent(uiContext, wrapBuilder, args)
      } else {
        this.popup = new ComponentContent(uiContext, wrapBuilder as WrappedBuilder<[]>)
      }
      this.promptAction = uiContext.getPromptAction()
      this.promptAction.openCustomDialog(this.popup, config)
    } catch (e) {
      console.error(JSON.stringify(e))
    }
  }

  /**
   * 关闭弹窗
   */
  async dismiss() {
    try {
      const windowClass = await window.getLastWindow(getContext())
      this.promptAction?.closeCustomDialog(this.popup)
    } catch (e) {
      console.error(JSON.stringify(e))
    }
  }
}

使用

typescript 复制代码
Button('show dialog')
        .onClick(() => {
          let dialog = DialogUtil.createAlertDialog({ title: "title", message: 'message' })
          dialog.show()
        })
相关推荐
不爱吃糖的程序媛1 小时前
Flutter-OH 三方库 devicelocale 鸿蒙适配
flutter·华为·harmonyos
加农炮手Jinx10 小时前
Flutter for OpenHarmony 实战:JWT — 构建安全的无状态认证中心
网络·flutter·华为·harmonyos·鸿蒙
左手厨刀右手茼蒿10 小时前
Flutter for OpenHarmony: Flutter 三方库 hashlib 为鸿蒙应用提供军用级加密哈希算法支持(安全数据完整性卫士)
安全·flutter·华为·c#·哈希算法·linq·harmonyos
王码码203510 小时前
Flutter for OpenHarmony: Flutter 三方库 cryptography 在鸿蒙上实现金融级现代加解密(高性能安全库)
android·安全·flutter·华为·金融·harmonyos
亚历克斯神11 小时前
Flutter for OpenHarmony:Flutter 三方库 yaml_edit 精准修改 YAML 文件内容(保留注释与格式的编辑神器)
android·flutter·华为·harmonyos
加农炮手Jinx12 小时前
Flutter for OpenHarmony:image_picker 插件鸿蒙化适配指南
flutter·华为·harmonyos
左手厨刀右手茼蒿12 小时前
Flutter for OpenHarmony: Flutter 三方库 image_size_getter 零加载极速获取图片尺寸(鸿蒙 UI 布局优化必备)
android·服务器·flutter·ui·华为·harmonyos
亚历克斯神12 小时前
Flutter for OpenHarmony:zxing2 纯 Dart 条码扫描与生成库(不仅是扫码,更是编解码引擎) 深度解析与鸿蒙适配指南
android·flutter·华为·harmonyos
钛态12 小时前
Flutter for OpenHarmony:dio_cookie_manager 让 Dio 发挥会话管理能力,像浏览器一样自动处理 Cookie 深度解析与鸿蒙适配指南
android·linux·运维·flutter·ui·华为·harmonyos