ArkUI CustomDialog:弹窗可以自定义,但别一上来写复杂业务

举报
蓝瘦的蜕变 发表于 2026/09/09 21:55:13 2026/09/09
【摘要】 今天我们用 CustomDialog 做一个最小自定义弹窗。固定样式弹窗不够用时,我们才需要自定义。自定义不是把一整套业务都塞进弹窗里,而是让内容结构更贴合当前场景。我们这篇只做标题、说明、关闭按钮。 写一个弹窗结构自定义弹窗先用 @CustomDialog 单独声明。@CustomDialogstruct SimpleCustomDialog { controller: CustomDi...

今天我们用 CustomDialog 做一个最小自定义弹窗。

固定样式弹窗不够用时,我们才需要自定义。自定义不是把一整套业务都塞进弹窗里,而是让内容结构更贴合当前场景。我们这篇只做标题、说明、关闭按钮。

写一个弹窗结构

自定义弹窗先用 @CustomDialog 单独声明。

@CustomDialog
struct SimpleCustomDialog {
  controller: CustomDialogController

  build() {
    Column() {
      Text('自定义弹窗')
      Button('我知道了')
        .onClick(() => {
          this.controller.close()
        })
    }
  }
}

controller 用来关闭当前弹窗。弹窗里只做自己的收尾动作,不做数据同步。

创建控制器

页面里创建 CustomDialogController

private dialogController: CustomDialogController = new CustomDialogController({
  builder: SimpleCustomDialog(),
  autoCancel: true,
  alignment: DialogAlignment.Center
})

builder 指向弹窗内容,autoCancel 允许点击外部区域关闭,alignment 控制弹窗位置。这里放在屏幕中间,先保持最常见写法。

点击按钮打开

页面按钮里调用 open()

Button('打开自定义弹窗')
  .onClick(() => {
    this.dialogController.open()
  })

到这一步,自定义弹窗的打开和关闭就完整了。后面如果要做输入、校验、数据回传,建议单独开一篇,不要把第一篇写得太重。

你在项目里最常见的自定义弹窗是什么?活动提示、二次确认、还是一段需要特别排版的说明?这个问题能帮你判断是不是该用自定义弹窗。

完整代码

@CustomDialog
struct SimpleCustomDialog {
  controller: CustomDialogController

  build() {
    Column({ space: 16 }) {
      Text('自定义弹窗')
        .fontSize(22)
        .fontWeight(FontWeight.Bold)
        .fontColor('#111827')
      Text('这里可以自己安排标题、说明和按钮。案例只做展示和关闭,不写复杂业务。')
        .fontSize(14)
        .fontColor('#4B5563')
        .lineHeight(22)
        .textAlign(TextAlign.Center)
      Button('我知道了')
        .width('100%')
        .height(42)
        .borderRadius(21)
        .fontColor('#FFFFFF')
        .backgroundColor('#2563EB')
        .onClick(() => {
          this.controller.close()
        })
    }
    .width(300)
    .padding(22)
    .borderRadius(18)
    .backgroundColor('#FFFFFF')
  }
}

@Entry
@Component
struct ArkUICustomDialogDemo {
  private dialogController: CustomDialogController = new CustomDialogController({
    builder: SimpleCustomDialog(),
    autoCancel: true,
    alignment: DialogAlignment.Center
  })

  @Builder
  sectionTitle(title: string, desc: string) {
    Column({ space: 6 }) {
      Text(title)
        .fontSize(19)
        .fontWeight(FontWeight.Bold)
        .fontColor('#111827')
      Text(desc)
        .fontSize(13)
        .fontColor('#6B7280')
        .lineHeight(20)
    }
    .width('100%')
    .alignItems(HorizontalAlign.Start)
  }

  @Builder
  infoCard(title: string, desc: string, color: string) {
    Row({ space: 12 }) {
      Text(title.substring(0, 1))
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .textAlign(TextAlign.Center)
        .width(34)
        .height(34)
        .borderRadius(17)
        .backgroundColor(color)

      Column({ space: 4 }) {
        Text(title)
          .fontSize(15)
          .fontWeight(FontWeight.Bold)
          .fontColor('#111827')
        Text(desc)
          .fontSize(12)
          .fontColor('#6B7280')
          .lineHeight(18)
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .padding(12)
    .borderRadius(12)
    .backgroundColor('#FFFFFF')
    .border({ width: 1, color: '#E5E7EB' })
  }

  build() {
    Scroll() {
      Column({ space: 22 }) {
        Column({ space: 8 }) {
          Text('ArkUI CustomDialog')
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor('#111827')
          Text('弹窗可以自定义,但别一上来写复杂业务')
            .fontSize(16)
            .fontColor('#4B5563')
          Text('CustomDialog 适合固定样式弹窗不够用的时候。先把结构、控制器和关闭方式讲清楚。')
            .fontSize(14)
            .fontColor('#6B7280')
            .lineHeight(22)
        }
        .width('100%')
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('控制器负责打开和关闭', '页面里创建 CustomDialogController,按钮点击时调用 open,弹窗内点击按钮时调用 close。')
        Column({ space: 14 }) {
          Text('这里的弹窗只有标题、说明和一个关闭按钮。自定义不等于一上来就做完整流程。')
            .fontSize(14)
            .fontColor('#4B5563')
            .lineHeight(22)
            .width('100%')

          Button('打开自定义弹窗')
            .fontSize(14)
            .fontColor('#FFFFFF')
            .backgroundColor('#2563EB')
            .borderRadius(20)
            .height(40)
            .padding({ left: 20, right: 20 })
            .onClick(() => {
              this.dialogController.open()
            })
        }
        .width('100%')
        .padding(16)
        .borderRadius(14)
        .backgroundColor('#FFFFFF')
        .border({ width: 1, color: '#E5E7EB' })
        .alignItems(HorizontalAlign.Start)

        this.sectionTitle('先记住这三个点', '这篇只写最基础的自定义弹窗,不做输入、校验或数据回传。')
        Column({ space: 10 }) {
          this.infoCard('@CustomDialog', '把弹窗内容单独写成一个结构。', '#2563EB')
          this.infoCard('CustomDialogController', '负责 builder、autoCancel、alignment 和打开关闭。', '#0F766E')
          this.infoCard('close', '弹窗内的按钮直接关闭当前弹窗。', '#C2410C')
        }
        .width('100%')
      }
      .width('100%')
      .padding(24)
      .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F8FAFC')
  }
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。