自学鸿蒙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: '我是来自最顶层的文字',

      })
    }
  }
}
相关推荐
熊猫钓鱼>_>37 分钟前
ArkTS 性能优化实战:从冷启动到长列表,一套可复现的实测方法论
app·harmonyos·arkts·鸿蒙·组件·性能·arkui
熊猫钓鱼>_>41 分钟前
从拍照到建模:HarmonyOS 7 3DGS端侧重建完整实战指南
人工智能·3d·ai·harmonyos·arkts·鸿蒙·3dgs
李游Leo1 小时前
HarmonyOS 7 实战开发 04:适配手机、折叠屏与大屏布局
ios·harmonyos
衝鋒壹号1 小时前
鸿蒙 PC 能跑 Docker 吗?一次从安装失败到成功运行的实测记录
后端·harmonyos
Latte Moments开发1 小时前
Harmony鸿蒙实战开发-浏览器app【源码在文末】
华为·harmonyos
柒儿吖1 小时前
SSCom 重构全记录:用 Rust 把串口调试助手送上鸿蒙 PC、macOS、Windows和Linux
测试工具·rust·harmonyos
李游Leo2 小时前
HarmonyOS 7 端侧 AI 视觉能力实战 06:把识别、增强与搜索串成完整处理链
harmonyos
大雷神2 小时前
【共创稿事节】ArkGraphics 3D开发环境安装实战:从官网下载编辑器,到 DevEco Studio 离线装插件
harmonyos
李游Leo2 小时前
HarmonyOS 7 实战开发 02:用状态驱动复杂页面交互
harmonyos
大雷神2 小时前
【共创稿事节】HarmonyOS ArkGraphics 3D 实操——给智能音箱做一台结构探索台
harmonyos