自学鸿蒙HarmonyOS的ArkTS语言<九>自定义弹窗组件CustomDialog及二次封装自定义弹窗

一、自定义弹窗
java 复制代码
@CustomDialog
struct CustomDialogBuilder {
  controller: CustomDialogController = new CustomDialogController({ // 注意写法
    builder: CustomDialogBuilder({})
  })

  // controller: CustomDialogController // 这种预览会报错
  cancel?: () => void
  confirm?: () => void
  text?: string

  build() {
    Column() {
      Text(this.text)
        .padding(20)
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('取消')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            this.controller.close() // 关闭弹窗
            if (this.cancel) {
              this.cancel()
            }
          })
        Button('确定')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            if (this.confirm) {
              this.confirm()
            }
        })
      }.padding(10)

    }
  }
}

@Entry
@Component
struct Index6 {
  @State text: string = '我是来自父组件的内容'
  dialogController: CustomDialogController | null = new CustomDialogController({
    // builder->自定义弹窗内容构造器
    builder: CustomDialogBuilder({
      cancel: () => { this.onCancel() }, // 不能写成 () => this.onCancel()
      confirm: () => { this.onAccept() },
      text: this.text
    }),
    alignment: DialogAlignment.Center,
    autoCancel: true,
    cancel: () => {
      console.log('点击遮罩层')
    },
    onWillDismiss: (res: DismissDialogAction) => { // 有了onWillDismiss不会触发cancel
      console.log('onWillDismiss:', JSON.stringify(res))
    }
    // ... 还可以设置backgroundColor, cornerRadius等
  })

  // 在自定义组件即将析构销毁时将dialogController置空
  aboutToDisappear() {
    this.dialogController = null // 将dialogController置空
  }

  onCancel() {
    console.log('我是父组件中的onCancel')
  }

  onAccept() {
    console.log('我是父组件中的onAccept')
  }

  build() {
    Button('点击我可以获取一个自定义弹窗')
      .onClick(() => {
        if (this.dialogController !== null) { // dialogController有null类型,必须判断否则报错
          this.text = '我是来自父组件中的内容2'
          this.dialogController.open() // 打开弹窗
        }
      })
  }
}

注意点:

1、自定义弹窗用 @CustomDialog 装饰

2、和普通组件不一样的是自定义弹窗是通过实例化CustomDialogController类显示的,其内容是builder参数(自定义弹窗内容构造器)

3、构造器里面传参的写法

4、自定义函数中controller用下面这种方式,预览会报错 ??? 不明白

二、二次封装自定义弹窗组件
java 复制代码
@CustomDialog
struct CustomDialogBuilder {
  @Link visible: boolean
  controller: CustomDialogController = new CustomDialogController({ // 注意写法
    builder: CustomDialogBuilder({
      visible: $visible
    })
  })

  // controller: CustomDialogController // 这种预览会报错
  cancel?: () => void
  confirm?: () => void
  text?: string

  build() {
    Column() {
      Text(this.text)
        .padding(20)
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('取消')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            this.visible = false
            this.controller.close() // 关闭弹窗
            if (this.cancel) {
              this.cancel()
            }
          })
        Button('确定')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            this.visible = false
            if (this.confirm) {
              this.confirm()
            }
        })
      }.padding(10)

    }
  }
}

// 二次封装
@Component
struct Dialog {
  @Watch('onChange') @Link visible: boolean // 必须在@link前,否则报错
  cancel?: () => void
  confirm?: () => void
  text?: string

  private controller = new CustomDialogController({
    builder: CustomDialogBuilder({
      cancel: this.cancel,
      confirm: this.confirm,
      visible: $visible,
      text: this.text
    }),
    alignment: DialogAlignment.Center,
    autoCancel: true,
    cancel: () => {
      console.log('点击遮罩层')
    },
    onWillDismiss: (res: DismissDialogAction) => {
      console.log('onWillDismiss:', JSON.stringify(res))
    }
  })

  onChange() {
    console.log('监听visible:', this.visible)
    if (this.visible) {
      this.controller.open()
    } else {
      this.controller.close()
    }
  }

  build() {
  }
}

@Entry
@Component
struct Index6 {
  @State visible: boolean = false

  onCancel() {
    console.log('我是来自最顶层的onCancel')
  }

  onConfirm() {
    console.log('我是来自最顶层的onConfirm')
  }

  build() {
    Column() {
      Button('点击我可以获取一个自定义弹窗')
        .onClick(() => {
          this.visible = !this.visible
          console.log(this.visible+'')
        })

      Dialog({
        visible: this.visible,
        cancel: () => {
          console.log('我是来自最顶层的oncancel')
        },
        confirm: () => {
          console.log('我是来自最顶层的onConfirm')
        },
        text: '我是来自最顶层的文字',

      })
    }
  }
}
相关推荐
Android技术栈4 小时前
鸿蒙(API 12 Beta2版)媒体开发【使用AudioRenderer开发音频播放功能】
程序员·移动开发·音视频·harmonyos·媒体·openharmony·鸿蒙开发
经海路大白狗7 小时前
探索移动应用中的 WebView:理解与应用
java·javascript·华为·harmonyos·webview
Android技术栈7 小时前
鸿蒙(API 12 Beta2版)NDK开发【LLDB高性能调试器】调试和性能分析
华为·harmonyos·openharmony·性能·ndk·调试器·鸿蒙开发
Bazinga bingo10 小时前
网络协议 从入门到精通系列讲解 - 总目录
网络·网络协议·华为·wireshark·ensp
轻口味11 小时前
HarmonyOS 音视频之音频采集实战
华为·音视频·harmonyos
爱桥代码的程序媛11 小时前
鸿蒙图形开发【3D引擎接口示例】
3d·华为·harmonyos·openharmony·鸿蒙开发·图形开发·引擎接口
Aic山鱼13 小时前
鸿蒙系统学习指南
分布式·科技·harmonyos
铸剑先生10013 小时前
HarmonyOS鸿蒙开发学习:鸿蒙基础-基础环境-ArkTS-组件-样式
学习·华为·harmonyos
工程师老罗13 小时前
HarmonyOS鸿蒙应用开发之Row & Colum组件的使用
华为·harmonyos
霹雳桃13 小时前
Harmony OS 卡片能力
harmonyos