HarmonyOS4.0从零开始的开发教程11给您的应用添加弹窗

HarmonyOS(十)给您的应用添加弹窗

概述

在我们日常使用应用的时候,可能会进行一些敏感的操作,比如删除联系人,这时候我们给应用添加弹窗来提示用户是否需要执行该操作,如下图所示:

弹窗是一种模态窗口,通常用来展示用户当前需要的或用户必须关注的信息或操作。在弹出框消失之前,用户无法操作其他界面内容。ArkUI为我们提供了丰富的弹窗功能,弹窗按照功能可以分为以下两类:

  • 确认类:例如警告弹窗AlertDialog。
  • 选择类:包括文本选择弹窗TextPickerDialog 、日期滑动选择弹窗DatePickerDialog、时间滑动选择弹窗TimePickerDialog等。

您可以根据业务场景,选择不同类型的弹窗。部分弹窗效果图如下:

此外,如果上述弹窗还不能满足您的需求,或者需要对弹窗的布局和样式进行自定义,您还可以使用自定义弹窗CustomDialog。

下文将分别介绍AlertDialog 、TextPickerDialog 、DatePickerDialog以及CustomDialog的使用。

警告弹窗

警告弹窗AlertDialog由以下三部分区域构成,对应下面的示意图:

  1. 标题区:为可选的。
  2. 内容区:显示提示消息。
  3. 操作按钮区:用户做"确认"或者"取消"等操作。

以下示例代码,演示了如何使用AlertDialog 实现上图所示的警告弹窗。AlertDialog可以设置两个操作按钮,示例代码中分别使用primaryButton和secondaryButton实现了"取消"和"删除"操作按钮,操作按钮可以通过action响应点击事件。

javascript 复制代码
Button('点击显示弹窗')
  .onClick(() => {
    AlertDialog.show(
      {
        title: '删除联系人', // 标题
        message: '是否需要删除所选联系人?', // 内容
        autoCancel: false, // 点击遮障层时,是否关闭弹窗。
        alignment: DialogAlignment.Bottom, // 弹窗在竖直方向的对齐方式
        offset: { dx: 0, dy: -20 }, // 弹窗相对alignment位置的偏移量
        primaryButton: {
          value: '取消',
          action: () => {
            console.info('Callback when the first button is clicked');
          }
        },
        secondaryButton: {
          value: '删除',
          fontColor: '#D94838',
          action: () => {
            console.info('Callback when the second button is clicked');
          }
        },
        cancel: () => { // 点击遮障层关闭dialog时的回调
          console.info('Closed callbacks');
        }
      }
    )
  })

此外,您还可以使用AlertDialog,构建只包含一个操作按钮的确认弹窗,使用confirm响应操作按钮回调。

javascript 复制代码
AlertDialog.show(
  {
    title: '提示',
    message: '提示信息',
    autoCancel: true,
    alignment: DialogAlignment.Bottom,
    offset: { dx: 0, dy: -20 },
    confirm: {
      value: '确认',
      action: () => {
        console.info('Callback when confirm button is clicked');
      }
    },
    cancel: () => {
      console.info('Closed callbacks')
    }
  }
)

选择类弹窗

选择类弹窗用于方便用户选择相关数据,比如选择喜欢吃的水果、出生日期等等。下面我们以TextPickerDialog和DatePickerDialog为例,来介绍选择类弹窗的使用。

文本选择弹窗

TextPickerDialog为文本滑动选择器弹窗,根据指定的选择范围创建文本选择器,展示在弹窗上,例如下面这段示例代码使用TextPickerDialog实现了一个水果选择弹窗。示例代码中使用selected指定了弹窗的初始选择项索引为2,对应的数据为"香蕉"。当用户点击"确定"操作按钮后,会触发onAccept事件回调,在回调中将选中的值,传递给宿主中的select变量。

javascript 复制代码
@Entry
@Component
struct TextPickerDialogDemo {
  @State select: number = 2;
  private fruits: string[] = ['苹果', '橘子', '香蕉', '猕猴桃', '西瓜'];

  build() {
    Column() {
      Button("TextPickerDialog")
        .margin(20)
        .onClick(() => {
          TextPickerDialog.show({
            range: this.fruits, // 设置文本选择器的选择范围
            selected: this.select, // 设置初始选中项的索引值。
            onAccept: (value: TextPickerResult) => { // 点击弹窗中的"确定"按钮时触发该回调。
              // 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项
              this.select = value.index;
              console.info("TextPickerDialog:onAccept()" + JSON.stringify(value));
            },
            onCancel: () => { // 点击弹窗中的"取消"按钮时触发该回调。
              console.info("TextPickerDialog:onCancel()");
            },
            onChange: (value: TextPickerResult) => { // 滑动弹窗中的选择器使当前选中项改变时触发该回调。
              console.info("TextPickerDialog:onChange()" + JSON.stringify(value));
            }
          })
        })
    }
    .width('100%')
  }
}

效果图如下:

日期选择弹窗

下面我们介绍另一种常用的选择类弹窗DatePickerDialog,它是日期滑动选择器弹窗,根据指定的日期范围创建日期滑动选择器,展示在弹窗上。DatePickerDialog的使用非常广泛,比如当我们需要输入个人出生日期的时候,就可以使用DatePickerDialog。下面的示例代码实现了一个日期选择弹窗:

javascript 复制代码
@Entry
@Component
struct DatePickerDialogDemo {
  selectedDate: Date = new Date("2010-1-1")

  build() {
    Column() {
      Button("DatePickerDialog")
        .margin(20)
        .onClick(() => {
          DatePickerDialog.show({
            start: new Date("1900-1-1"), // 设置选择器的起始日期
            end: new Date("2023-12-31"), // 设置选择器的结束日期
            selected: this.selectedDate, // 设置当前选中的日期
            lunar: false,
            onAccept: (value: DatePickerResult) => { // 点击弹窗中的"确定"按钮时触发该回调
              // 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期
              this.selectedDate.setFullYear(value.year, value.month, value.day)
              console.info("DatePickerDialog:onAccept()" + JSON.stringify(value))
            },
            onCancel: () => { // 点击弹窗中的"取消"按钮时触发该回调
              console.info("DatePickerDialog:onCancel()")
            },
            onChange: (value: DatePickerResult) => { // 滑动弹窗中的滑动选择器使当前选中项改变时触发该回调
              console.info("DatePickerDialog:onChange()" + JSON.stringify(value))
            }
          })
        })
    }
    .width('100%')
  }
}

效果图如下:

自定义弹窗

自定义弹窗的使用更加灵活,适用于更多的业务场景,在自定义弹窗中您可以自定义弹窗内容,构建更加丰富的弹窗界面。自定义弹窗的界面可以通过装饰器@CustomDialog定义的组件来实现,然后结合CustomDialogController来控制自定义弹窗的显示和隐藏。下面我们通过一个兴趣爱好的选择框来介绍自定义弹窗的使用。

从上面的效果图可以看出,这个选择框是一个多选的列表弹窗,我们可以使用装饰器@CustomDialog,结合List组件来完成这个弹窗布局,实现步骤如下:

  1. 初始化弹窗数据。

    先准备好资源文件和数据实体类。其中资源文件stringarray.json创建在resources/base/element目录下,文件根节点为strarray。

    javascript 复制代码
    {
      "strarray": [
        {
          "name": "hobbies_data",
          "value": [
            {
              "value": "Soccer"
            },
            {
              "value": "Badminton"
            },
            {
              "value": "Travelling"
            },
            ... 
          ]
        }
      ]
    }

    实体类HobbyBean用来封装自定义弹窗中的"兴趣爱好"数据。

    javascript 复制代码
    export default class HobbyBean {
      label: string;
      isChecked: boolean;
    }

    然后创建一个ArkTS文件CustomDialogWidget,用来封装自定义弹窗,使用装饰器@CustomDialog修饰CustomDialogWidget表示这是一个自定义弹窗。使用资源管理对象manager获取数据,并将数据封装到hobbyBeans。

    javascript 复制代码
    @CustomDialog
    export default struct CustomDialogWidget {
      @State hobbyBeans: HobbyBean[] = [];
    
      aboutToAppear() {
        let context: Context = getContext(this);
        let manager = context.resourceManager;
        manager.getStringArrayValue($r('app.strarray.hobbies_data'), (error, hobbyResult) => {
          ...
          hobbyResult.forEach((hobbyItem: string) => {
            let hobbyBean = new HobbyBean();
            hobbyBean.label = hobbyItem;
            hobbyBean.isChecked = false;
            this.hobbyBeans.push(hobbyBean);
          });
        });
      }
    
      build() {...}
    }
  2. 创建弹窗组件。

    controller对象用于控制弹窗的控制和隐藏,hobbies表示弹窗选中的数据结果。setHobbiesValue方法用于筛选出被选中的数据,赋值给hobbies。

    javascript 复制代码
    @CustomDialog
    export default struct CustomDialogWidget {
      @State hobbyBeans: HobbyBean[] = [];
      @Link hobbies: string;
      private controller: CustomDialogController;
    
      aboutToAppear() {...}
    
      setHobbiesValue(hobbyBeans: HobbyBean[]) {
        let hobbiesText: string = '';
        hobbiesText = hobbyBeans.filter((isCheckItem: HobbyBean) =>
        isCheckItem?.isChecked)
          .map((checkedItem: HobbyBean) => {
            return checkedItem.label;
          }).join(',');
        this.hobbies = hobbiesText;
      }
    
      build() {
        Column() {
          Text($r('app.string.text_title_hobbies'))...
          List() {
            ForEach(this.hobbyBeans, (itemHobby: HobbyBean) => {
              ListItem() {
                Row() {
                  Text(itemHobby.label)...
                  Toggle({ type: ToggleType.Checkbox, isOn: false })...
                    .onChange((isCheck) => {
                      itemHobby.isChecked = isCheck;
                    })
                }
              }
            }, itemHobby => itemHobby.label)
          }
    
          Row() {
            Button($r("app.string.cancel_button"))...
              .onClick(() => {
                this.controller.close();
              })
            Button($r("app.string.definite_button"))...
              .onClick(() => {
                this.setHobbiesValue(this.hobbyBeans);
                this.controller.close();
              })
          }
        }
      }
    }
  3. 使用自定义弹窗。

    在自定义弹窗的使用页面HomePage中先定义一个变量hobbies,使用装饰器@State修饰,和自定义弹窗中的@Link 装饰器修饰的变量进行双向绑定。然后我们使用alignment和offset设置弹窗的位置在屏幕底部,并且距离底部20vp。最后我们在自定义组件TextCommonWidget(具体实现可以参考《构建多种样式弹窗》Codelab源码)的点击事件中,调用customDialogController的open方法,用于显示弹窗。

    javascript 复制代码
    @Entry
    @Component
    struct HomePage {
      customDialogController: CustomDialogController = new CustomDialogController({
        builder: CustomDialogWidget({
          onConfirm: this.setHobbiesValue.bind(this),
        }),
        alignment: DialogAlignment.Bottom,
        customStyle: true,
        offset: { dx: 0,dy: -20 }
      });
    
      setHobbiesValue(hobbyArray: HobbyBean[]) {...}
    
      build() {
        ...
          TextCommonWidget({
            ...
            title: $r("app.string.title_hobbies"),
            content: $hobby,
            onItemClick: () => {
              this.customDialogController.open();
            }
          })
        ...
      }
    }

参考

关于更多弹窗,您可以参考:

警告弹窗

列表选择弹窗

自定义弹窗

日期滑动选择弹窗

时间滑动选择弹窗

文本滑动选择弹窗

相关推荐
大猫和小黄5 分钟前
Windows、CentOS环境下搭建自己的版本管理资料库:GitBlit
linux·服务器·windows·git
Schwertlilien26 分钟前
图像处理-Ch6-彩色图像处理
windows
程序猿会指北3 小时前
【鸿蒙(HarmonyOS)性能优化指南】启动分析工具Launch Profiler
c++·性能优化·harmonyos·openharmony·arkui·启动优化·鸿蒙开发
鸿蒙程序媛3 小时前
2024最新鸿蒙开发面试题合集-HarmonyOS NEXT Release(API 12 Release)
harmonyos·harmonyos面试题
轻口味4 小时前
【每日学点鸿蒙知识】DevEco、HDC报错、C调用数据库、测试工具、codegen
数据库·华为·harmonyos
小奥超人5 小时前
PDF无法打印!怎么办?
windows·经验分享·pdf·办公技巧·pdf加密解密
gywl8 小时前
openEuler VM虚拟机操作(期末考试)
linux·服务器·网络·windows·http·centos
某柚啊9 小时前
Windows开启IIS后依然出现http error 503.the service is unavailable
windows·http
码农君莫笑10 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
yg_小小程序员10 小时前
vue3中使用vuedraggable实现拖拽
typescript·vue