大家在开发 HarmonyOS 应用时,肯定少不了和弹窗打交道。今天咱们就来聊聊 ArkUI 里的 DialogV2 组件,这可是从 API version 18 开始支持的新玩意儿,比之前的版本好用太多啦!咱们会从最基础的导入讲起,一直到各种实战案例,保证让你看完就能上手用。

一、DialogV2 基础概念与核心优势

1.1 什么是 DialogV2?

简单来说,DialogV2 就是一种模态窗口。啥叫模态窗口呢?就是说它弹出来之后,用户必须跟它交互(比如点个按钮)才能继续操作主界面,不然它就一直挡在那儿。这种设计特别适合展示需要用户立即关注的信息,比如确认删除、选择选项这些场景。

1.2 状态管理 V2 的魔力

DialogV2 基于状态管理 V2 实现,这可是个大亮点!相比之前的 V1 版本,它能更深入地观察和管理数据对象,而且不再局限于组件层级。打个比方,以前可能某个组件的数据变了,界面刷新得绕好几个弯,现在 V2 能直接抓住数据变化,瞬间刷新界面,效率高多了。开发者用起来也更灵活,控制弹窗的数据和状态就像玩一样。

1.3 支持设备与导入方式

DialogV2 支持的设备还挺多:Phone、PC/2in1、Tablet、TV 都能用,不过 Wearable 设备暂时不支持哦。要使用它,先得在代码里导入相关模块,一行代码搞定:

import { TipsDialogV2, SelectDialogV2, ConfirmDialogV2, AlertDialogV2, LoadingDialogV2, CustomContentDialogV2, PopoverDialogV2 } from '@kit.ArkUI';

二、TipsDialogV2:带图标的提示弹窗

2.1 核心功能与应用场景

TipsDialogV2 是最常用的提示弹窗之一,最大的特点是可以带图标,用图形化的方式展示信息,特别直观。比如用户要卸载 APP 时,弹个带警告图标的提示框,问问是否确定卸载,这种场景就很适合用它。

2.2 必知参数与配置重点

  • imageRes:必填项,就是弹窗里显示的图片,可以是资源路径或者 PixelMap 对象。
  • title/content:标题和内容文本,默认不显示,超过两行会显示省略号。
  • checkTips/checked:勾选框的提示内容和状态,比如 “不再提示” 这种选项。
  • primaryButton/secondaryButton:左右两侧的按钮,可以自定义内容和点击事件。

2.3 实战代码示例

import { TipsDialogV2, AdvancedDialogV2Button, UIContext } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Local checked: boolean = false;

  @Builder
  dialogBuilder(): void {
    TipsDialogV2({
      imageRes: $r('sys.media.ohos_ic_public_voice'), // 必选图标
      content: '想要卸载这个APP嘛?', // 提示内容
      title: 'TipsDialogV2', // 标题
      checkTips: '不再提示', // 勾选提示
      checked: this.checked, // 勾选状态
      primaryButton: new AdvancedDialogV2Button({
        content: '取消',
        action: () => {
          console.info('取消按钮被点击');
        },
      }),
      secondaryButton: new AdvancedDialogV2Button({
        content: '删除',
        role: ButtonRole.ERROR, // 错误类型按钮,样式更醒目
        action: () => {
          console.info('确认删除按钮被点击');
        }
      }),
      onCheckedChange: (checked: boolean) => {
        console.info('勾选状态改变');
        this.checked = checked;
      }
    })
  }

  build() {
    Row() {
      Stack() {
        Column() {
          Button("打开TipsDialogV2弹窗")
            .width(96)
            .height(40)
            .onClick(() => {
              let uiContext: UIContext = this.getUIContext();
              uiContext.getPromptAction().openCustomDialog({
                builder: () => {
                  this.dialogBuilder();
                },
              });
            })
        }.margin({ bottom: 300 })
      }.align(Alignment.Bottom)
      .width('100%').height('100%')
    }
    .backgroundImageSize({ width: '100%', height: '100%' })
    .height('100%')
  }
}

这段代码里,我们创建了一个带图标的提示弹窗,用户点击按钮后弹出,询问是否卸载 APP,还有一个 “不再提示” 的勾选框,左右两侧分别是取消和删除按钮,删除按钮用了 ERROR 角色,颜色会更醒目,提醒用户这是个危险操作。

三、SelectDialogV2:列表选择弹窗

3.1 适用场景与核心功能

当你需要让用户从多个选项中选一个时,SelectDialogV2 就派上用场了。比如选择日期、选择城市、选择偏好设置等等,它会以列表或网格的形式展示选项,用户点击即可选中。

3.2 关键参数解析

  • title:必填项,弹窗的标题,超过两行显示省略号。
  • radioContent:必填项,选项内容列表,每个选项包含文本和选中回调事件。
  • selectedIndex:当前选中项的索引,默认 - 1 表示未选中。
  • confirm:底部的确认按钮,默认不显示。

3.3 代码实战:纯列表选择弹窗

import { SelectDialogV2, AdvancedDialogV2Button, UIContext } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Local radioIndex: number = 0; // 选中项索引

  @Builder
  dialogBuilder(): void {
    SelectDialogV2({
      title: '文本标题', // 必选标题
      selectedIndex: this.radioIndex, // 当前选中项
      confirm: new AdvancedDialogV2Button({
        content: '取消',
        action: () => {},
      }),
      radioContent: [
        {
          title: '文本文本文本文本文本', // 选项1
          action: () => {
            this.radioIndex = 0
          }
        },
        {
          title: '文本文本文本文本', // 选项2
          action: () => {
            this.radioIndex = 1
          }
        },
        {
          title: '文本文本文本文本', // 选项3
          action: () => {
            this.radioIndex = 2
          }
        },
      ]
    })
  }

  build() {
    Row() {
      Stack() {
        Column() {
          Button("纯列表弹出框")
            .width(96)
            .height(40)
            .onClick(() => {
              let uiContext: UIContext = this.getUIContext();
              uiContext.getPromptAction().openCustomDialog({
                builder: () => {
                  this.dialogBuilder();
                }
              })
            })
        }.margin({ bottom: 300 })
      }.align(Alignment.Bottom)
      .width('100%').height('100%')
    }
    .backgroundImageSize({ width: '100%', height: '100%' })
    .height('100%')
  }
}

这个例子中,我们创建了一个包含三个选项的列表弹窗,标题是 “文本标题”,底部有一个取消按钮。用户点击选项时,会更新 selectedIndex 的值,这样就能知道用户选了哪个选项啦。

四、ConfirmDialogV2:信息确认弹窗

4.1 功能特点与使用场景

ConfirmDialogV2 主要用于操作反馈,比如网络错误、电池电量过低,或者指纹录入失败等情况,弹出提示信息,有时候还会带一个勾选框,比如 “不再提示” 之类的选项。

4.2 重点参数说明

  • title:必填标题,显示错误或提示信息的主题。
  • content:详细内容,默认不显示。
  • checkTips/checked/onCheckedChange:勾选框相关参数,和 TipsDialogV2 类似。
  • primaryButton/secondaryButton:左右按钮,比如 “禁止” 和 “允许”。

4.3 代码示例:带勾选的确认弹窗

import { ConfirmDialogV2, AdvancedDialogV2Button, UIContext } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Local checked: boolean = false; // 勾选状态

  @Builder
  dialogBuilder(): void {
    ConfirmDialogV2({
      title: '文本标题', // 必选标题
      content: '文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本', // 详细内容
      checked: this.checked, // 勾选状态
      checkTips: '禁止后不再提示', // 勾选提示
      primaryButton: new AdvancedDialogV2Button({
        content: '禁止',
        action: () => {
          // 禁止操作逻辑
        },
      }),
      secondaryButton: new AdvancedDialogV2Button({
        content: '允许',
        action: () => {
          this.checked = false;
          console.info('允许操作被点击');
        }
      }),
      onCheckedChange: (checked: boolean) => {
        console.info('勾选状态改变');
        this.checked = checked;
      },
    })
  }

  build() {
    Row() {
      Stack() {
        Column() {
          Button("打开ConfirmDialogV2弹窗")
            .width(96)
            .height(40)
            .onClick(() => {
              let uiContext: UIContext = this.getUIContext();
              uiContext.getPromptAction().openCustomDialog({
                builder: () => {
                  this.dialogBuilder();
                },
                alignment: DialogAlignment.Bottom
              });
            })
        }.margin({ bottom: 300 })
      }.align(Alignment.Bottom)
      .width('100%').height('100%')
    }
    .backgroundImageSize({ width: '100%', height: '100%' })
    .height('100%')
  }
}

这个弹窗常用于权限申请场景,比如应用需要获取位置信息,弹出确认框问用户是否允许,同时有一个 “禁止后不再提示” 的选项,用户勾选后,下次就不会再弹这个框了。

五、AlertDialogV2:危险操作确认弹窗

5.1 与 ConfirmDialogV2 的区别

AlertDialogV2 也是确认弹窗,但它用于更严重的场景,比如触发不可逆操作时,像删除文件、重置设置、取消编辑等。它和 ConfirmDialogV2 的区别在于,AlertDialogV2 通常用于警告用户操作的严重后果,而 ConfirmDialogV2 更多是普通的信息确认。

5.2 关键参数介绍

  • content:必填项,显示操作的具体内容和后果。
  • primaryTitle/secondaryTitle:一级和二级标题,默认不显示。
  • primaryButton/secondaryButton:通常是 “取消” 和 “确认” 按钮,确认按钮会用危险样式。

5.3 代码实例:删除确认弹窗

import { AlertDialogV2, AdvancedDialogV2Button, UIContext } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Builder
  dialogBuilder(): void {
    AlertDialogV2({
      primaryTitle: '弹框一级标题', // 一级标题
      secondaryTitle: '弹框二级标题', // 二级标题
      content: '确定要删除这个文件吗?此操作不可恢复!', // 必选内容,说明后果
      primaryButton: new AdvancedDialogV2Button({
        content: '取消',
        action: () => {
          // 取消删除逻辑
        },
      }),
      secondaryButton: new AdvancedDialogV2Button({
        content: '确认',
        role: ButtonRole.ERROR, // 错误角色,红色样式
        action: () => {
          console.info('确认删除按钮被点击');
          // 执行删除逻辑
        }
      }),
    })
  }

  build() {
    Row() {
      Stack() {
        Column() {
          Button("打开AlertDialogV2弹窗")
            .width(96)
            .height(40)
            .onClick(() => {
              let uiContext: UIContext = this.getUIContext();
              uiContext.getPromptAction().openCustomDialog({
                builder: () => {
                  this.dialogBuilder();
                }
              });
            })
        }.margin({ bottom: 300 })
      }.align(Alignment.Bottom)
      .width('100%').height('100%')
    }
    .backgroundImageSize({ width: '100%', height: '100%' })
    .height('100%')
  }
}

这个例子模拟了删除文件的确认场景,内容里明确告诉用户操作不可恢复,确认按钮用了 ERROR 角色,显示为红色,进一步提醒用户这是个危险操作,避免误触。

六、LoadingDialogV2:进度加载弹窗

6.1 简单实用的加载提示

LoadingDialogV2 是最简洁的弹窗之一,主要用于显示操作正在进行中,比如加载数据、上传文件等。它默认显示一个旋转的进度图标,也可以添加文本内容,告诉用户正在做什么。

6.2 唯一参数:content

  • content:可选参数,加载时的提示文本,比如 “正在加载数据...”,超过十行会显示省略号。

6.3 代码示例:显示加载状态

import { LoadingDialogV2, UIContext } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Builder
  dialogBuilder(): void {
    LoadingDialogV2({
      content: '数据加载中...请稍候', // 加载提示文本
    })
  }

  build() {
    Row() {
      Stack() {
        Column() {
          Button("打开LoadingDialogV2弹窗")
            .width(96)
            .height(40)
            .onClick(() => {
              let uiContext: UIContext = this.getUIContext();
              uiContext.getPromptAction().openCustomDialog({
                builder: () => {
                  this.dialogBuilder();
                }
              });
            })
        }.margin({ bottom: 300 })
      }.align(Alignment.Bottom)
      .width('100%').height('100%')
    }
    .backgroundImageSize({ width: '100%', height: '100%' })
    .height('100%')
  }
}

这个弹窗很简单,点击按钮后弹出一个带 “数据加载中... 请稍候” 文本的加载框,让用户知道应用没有卡死,正在处理请求。实际使用中,通常会在数据请求开始时显示这个弹窗,请求完成后关闭。

七、CustomContentDialogV2:自定义内容弹窗

7.1 灵活强大的自定义能力

如果你觉得前面的弹窗都不够灵活,那 CustomContentDialogV2 绝对能满足你。它允许你完全自定义弹窗的内容区,想放什么就放什么,文本、按钮、列表、图片,甚至自定义组件都可以,同时还能配置标题和操作按钮。

7.2 核心参数说明

  • contentBuilder:必填项,自定义内容的构建函数,用 @Builder 装饰器定义。
  • primaryTitle/secondaryTitle:标题和辅助文本。
  • buttons:操作区按钮数组,最多支持 4 个按钮。

7.3 实战代码:自定义复杂弹窗

import { CustomContentDialogV2, AdvancedDialogV2Button, UIContext } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Builder
  dialogBuilder(): void {
    CustomContentDialogV2({
      primaryTitle: '标题', // 弹窗标题
      secondaryTitle: '辅助文本', // 辅助文本
      contentBuilder: () => {
        this.buildContent(); // 自定义内容区
      },
      buttons: [
        new AdvancedDialogV2Button({
          content: '按钮1', 
          buttonStyle: ButtonStyleMode.TEXTUAL, // 文本样式按钮
          action: () => {
            console.info('按钮1被点击');
          }
        }),
        new AdvancedDialogV2Button({
          content: '按钮2', 
          buttonStyle: ButtonStyleMode.TEXTUAL, 
          role: ButtonRole.ERROR, // 错误角色
        })
      ],
    })
  }

  build() {
    Column() {
      Button("打开CustomContentDialogV2弹窗")
        .onClick(() => {
          let uiContext: UIContext = this.getUIContext();
          uiContext.getPromptAction().openCustomDialog({
            builder: () => {
              this.dialogBuilder();
            }
          })
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }

  @Builder
  buildContent(): void {
    Column() {
      Text('内容区')
        .fontSize(16)
        .margin(10);
      Text('这是自定义的内容,可以放任何组件')
        .fontSize(14)
        .fontColor('#888888')
        .margin(5);
      Image($r('app.media.icon'))
        .width(50)
        .height(50)
        .margin(10);
    }
    .padding(10)
    .backgroundColor('#F5F5F5')
    .cornerRadius(8)
  }
}

这个例子中,我们自定义了一个内容区,包含文本和图片,标题是 “标题”,辅助文本是 “辅助文本”,底部有两个文本样式的按钮。通过 contentBuilder,你可以完全按照自己的需求构建弹窗内容,实现各种复杂的交互场景。

八、PopoverDialogV2:跟手弹窗

8.1 基于目标组件的弹窗

PopoverDialogV2 是一种很有意思的弹窗,它会基于某个目标组件的位置弹出,比如点击一个按钮后,在按钮旁边弹出一个菜单,这种效果就像跟手一样,所以叫跟手弹窗。前面介绍的所有 Dialog 组件都可以作为它的内容。

8.2 关键参数与实现要点

  • visible:必填项,控制弹窗的显示状态。
  • targetBuilder:必填项,定义目标组件,弹窗会基于这个组件的位置弹出。
  • popover:配置弹窗的参数,包括内容构建函数。
  • $visible:显示状态变化的回调事件,建议用双向绑定。

8.3 代码示例:按钮旁边的跟手弹窗

import { AlertDialogV2, PopoverDialogV2, PopoverDialogV2Options, AdvancedDialogV2Button } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Local isShow: boolean = false; // 弹窗显示状态
  @Local popoverOptions: PopoverDialogV2Options = {
    builder: () => {
      this.dialogBuilder(); // 弹窗内容
    }
  }

  @Builder dialogBuilder() {
    AlertDialogV2({
      content: '跟手弹出框', // 弹窗内容
      primaryButton: new AdvancedDialogV2Button({
        content: '取消',
        action: () => {
          this.isShow = false; // 关闭弹窗
        },
      }),
      secondaryButton: new AdvancedDialogV2Button({
        content: '确认',
        action: () => {
          this.isShow = false; // 关闭弹窗
        },
      }),
    });
  }

  @Builder buttonBuilder() {
    Button('跟手弹窗目标组件').onClick(() => {
      this.isShow = true; // 显示弹窗
    });
  }

  build() {
    Column() {
      PopoverDialogV2({
        visible: this.isShow!!, // 双向绑定显示状态
        popover: this.popoverOptions, // 弹窗配置
        targetBuilder: () => {
          this.buttonBuilder(); // 目标组件
        },
      })
    }
  }
}

这个例子中,我们点击 “跟手弹窗目标组件” 按钮后,会在按钮旁边弹出一个 AlertDialogV2 作为内容的跟手弹窗,用户点击取消或确认按钮后,弹窗关闭。这种跟手弹窗在菜单、下拉选项等场景中非常实用,能让交互更加直观和便捷。

九、AdvancedDialogV2Button:弹窗按钮详解

9.1 按钮配置全解析

弹窗里的按钮都是 AdvancedDialogV2Button 类型,它有很多可配置的参数,让你可以灵活定义按钮的样式和行为:

  • content:必填项,按钮文本。
  • action:点击事件回调函数。
  • background/fontColor:背景色和字体颜色。
  • buttonStyle:按钮样式,有 NORMAL、TEXTUAL 等模式。
  • role:按钮角色,如 ERROR、PRIMARY,会影响样式。
  • defaultFocus:是否默认获取焦点。
  • enabled:是否可用。

9.2 按钮样式对比代码

import { CustomContentDialogV2, AdvancedDialogV2Button, UIContext } from '@kit.ArkUI';

@Entry
@ComponentV2
struct Index {
  @Builder
  dialogBuilder(): void {
    CustomContentDialogV2({
      primaryTitle: '按钮样式示例',
      contentBuilder: () => {
        Column() {
          Text('不同样式的按钮对比:').fontSize(16).margin(10);
          Text('1. NORMAL样式(默认)').fontSize(14).margin(5);
          Text('2. TEXTUAL样式(文本按钮)').fontSize(14).margin(5);
          Text('3. ERROR角色(红色文本)').fontSize(14).margin(5);
        }
        .padding(10)
      },
      buttons: [
        new AdvancedDialogV2Button({
          content: 'NORMAL',
          action: () => {}
        }),
        new AdvancedDialogV2Button({
          content: 'TEXTUAL',
          buttonStyle: ButtonStyleMode.TEXTUAL,
          action: () => {}
        }),
        new AdvancedDialogV2Button({
          content: 'ERROR',
          role: ButtonRole.ERROR,
          action: () => {}
        })
      ],
    })
  }

  build() {
    Column() {
      Button("查看按钮样式")
        .onClick(() => {
          let uiContext: UIContext = this.getUIContext();
          uiContext.getPromptAction().openCustomDialog({
            builder: () => {
              this.dialogBuilder();
            }
          })
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

通过这个例子,你可以直观看到不同样式和角色的按钮效果。NORMAL 样式是默认的带背景色按钮,TEXTUAL 是纯文本按钮,ERROR 角色会让文本变成红色,用于突出危险操作按钮。

十、总结与最佳实践

10.1 组件选择指南

  • 显示带图标提示:用 TipsDialogV2。
  • 列表选择场景:用 SelectDialogV2。
  • 普通信息确认:用 ConfirmDialogV2。
  • 危险操作确认:用 AlertDialogV2。
  • 加载状态提示:用 LoadingDialogV2。
  • 自定义内容:用 CustomContentDialogV2。
  • 跟手弹窗:用 PopoverDialogV2。

10.2 最佳实践建议

  1. 避免频繁弹出弹窗,影响用户体验。
  2. 危险操作一定要用 AlertDialogV2,并明确提示后果。
  3. 加载弹窗要及时关闭,避免用户长时间等待。
  4. 自定义弹窗时,注意内容区的布局和适配,不要太复杂。
  5. 按钮样式和角色要合理使用,让用户一目了然操作的重要性。

通过这篇教程,相信你已经对 DialogV2 组件有了全面的了解,从基础用法到复杂的自定义场景都能轻松应对啦。赶紧动手试试吧,在实际开发中多运用这些弹窗组件,让你的应用交互体验更上一层楼!

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐