当前位置:   article > 正文

构建多种样式的弹窗_选择器弹框

选择器弹框

介绍

本篇Codelab将介绍如何使用弹窗功能,实现四种类型弹窗。分别是:警告弹窗、自定义弹窗、日期滑动选择器弹窗、文本滑动选择器弹窗。需要完成以下功能:

  1. 点击左上角返回按钮展示警告弹窗。
  2. 点击出生日期展示日期滑动选择器弹窗。
  3. 点击性别展示文本滑动选择器弹窗。
  4. 点击兴趣爱好(多选)展示自定义弹窗。

相关概念

完整示例

gitee源码地址

源码下载

构建多种样式弹窗(ArkTS).zip

环境搭建

我们首先需要完成HarmonyOS开发环境搭建,可参照如下步骤进行。

软件要求

硬件要求

  • 设备类型:华为手机或运行在DevEco Studio上的华为手机设备模拟器。
  • HarmonyOS系统:3.1.0 Developer Release。

环境搭建

  1. 安装DevEco Studio,详情请参考下载和安装软件
  2. 设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境: 
    • 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
    • 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境
  3. 开发者可以参考以下链接,完成设备调试的相关配置: 

代码结构解读

本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在源码下载或gitee中提供。

  1. ├──entry/src/main/ets // 代码区
  2. │ ├──common
  3. │ │ ├──constants
  4. │ │ │ └──CommonConstants.ets // 常量类
  5. │ │ └──utils
  6. │ │ ├──CommonUtils.ets // 弹窗操作工具类
  7. │ │ └──Logger.ets // 日志打印工具类
  8. │ ├──entryability
  9. │ │ └──EntryAbility.ets // 程序入口类
  10. │ ├──pages
  11. │ │ └──HomePage.ets // 主页面
  12. │ ├──view
  13. │ │ ├──CustomDialogWidget.ets // 自定义弹窗组件
  14. │ │ ├──TextCommonWidget.ets // 自定义Text组件
  15. │ │ └──TextInputWidget.ets // 自定义TextInput组件
  16. │ └──viewmodel
  17. │ └──HobbyItem.ets // 兴趣爱好类
  18. └──entry/src/main/resources // 资源文件目录

构建主页面

应用主页面采用Column容器嵌套自定义组件形式完成页面整体布局,效果如图所示:

从上面效果图可以看出,主界面由2个相同样式的文本输入框和3个相同样式的文本布局组成。我们可以将文本输入框抽取成TextInputWidget子组件。再将文本布局抽取成TextCommonWidget子组件。

在ets目录下,点击鼠标右键 > New > Directory,新建名为view的自定义子组件目录。然后在view目录下,点击鼠标右键 > New > ArkTS File,新建两个ArkTS文件,分别为TextInputWidget子组件、TextCommonWidget子组件。

文本输入框抽取成TextInputWidget子组件,效果如图所示:

  1. // TextInputWidget.ets
  2. @Component
  3. export default struct TextInputWidget {
  4. // 文本框左侧图片
  5. private inputImage?: Resource;
  6. // 文本框提示
  7. private hintText?: Resource;
  8. build() {
  9. Row() {
  10. Image(this.inputImage !== undefined ? this.inputImage : '')
  11. ...
  12. TextInput({ placeholder: this.hintText })
  13. ...
  14. }
  15. ...
  16. }
  17. }

文本布局抽取成TextCommonWidget子组件,效果如图所示:

  1. // TextCommonWidget.ets
  2. @Component
  3. export default struct TextCommonWidget {
  4. // 显示内容
  5. @Link content: string;
  6. // 文字标题左侧图片
  7. private textImage?: Resource;
  8. // 文本标题
  9. private title?: Resource;
  10. // 点击事件回调
  11. onItemClick = () => {};
  12. build() {
  13. Row() {
  14. Image(this.textImage !== undefined ? this.textImage : '')
  15. ...
  16. Text(this.title)
  17. ...
  18. Text(this.content)
  19. ...
  20. Image($r('app.media.ic_arrow'))
  21. ...
  22. }
  23. .onClick(this.onItemClick)
  24. ...
  25. }
  26. }

在HomePage主界面引用TextInputWidget和TextCommonWidget子组件,然后初始化出生日期、性别、兴趣爱好默认数据。

  1. // HomePage.ets
  2. @Entry
  3. @Component
  4. struct HomePage {
  5. @State birthdate: string = '';
  6. @State sex: string = '';
  7. @State hobbies: string = '';
  8. ...
  9. build() {
  10. Column() {
  11. ...
  12. TextInputWidget({
  13. inputImage: $r('app.media.ic_nickname'),
  14. hintText: $r('app.string.text_input_hint')
  15. })
  16. TextCommonWidget({
  17. textImage: $r('app.media.ic_birthdate'),
  18. title: $r('app.string.title_birthdate'),
  19. content: $birthdate,
  20. onItemClick: () => {
  21. CommonUtils.datePickerDialog((birthValue: string) => {
  22. this.birthdate = birthValue;
  23. });
  24. }
  25. })
  26. TextCommonWidget({
  27. textImage: $r('app.media.ic_sex'),
  28. title: $r('app.string.title_sex'),
  29. content: $sex,
  30. onItemClick: () => {
  31. CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {
  32. this.sex = sexValue;
  33. });
  34. }
  35. })
  36. TextInputWidget({
  37. inputImage: $r('app.media.ic_signature'),
  38. hintText: $r('app.string.text_input_signature')
  39. })
  40. TextCommonWidget({
  41. textImage: $r('app.media.ic_hobbies'),
  42. title: $r('app.string.title_hobbies'),
  43. content: $hobbies,
  44. onItemClick: () => {
  45. this.customDialogController.open();
  46. }
  47. })
  48. }
  49. ...
  50. }
  51. }

警告弹窗

点击主页面左上角返回按钮,通过CommonUtils.alertDialog方法弹出警告弹窗,提醒用户是否进行当前操作,效果如图所示:

 
  1. // CommonUtils.ets
  2. alertDialog(context: Context.UIAbilityContext) {
  3. AlertDialog.show({
  4. // 提示信息
  5. message: $r('app.string.alert_dialog_message'),
  6. // 弹窗显示位置
  7. alignment: DialogAlignment.Bottom,
  8. // 弹窗偏移位置
  9. offset: {
  10. dx: 0,
  11. dy: CommonConstants.DY_OFFSET
  12. },
  13. primaryButton: {
  14. value: $r('app.string.cancel_button'),
  15. action: () => {
  16. ...
  17. }
  18. },
  19. secondaryButton: {
  20. value: $r('app.string.definite_button'),
  21. action: () => {
  22. // 退出应用
  23. context.terminateSelf();
  24. ...
  25. }
  26. }
  27. });
  28. }

日期滑动选择器弹窗

点击出生日期选项,通过CommonUtils.datePickerDialog方法弹出日期选择器弹窗,根据需要选择相应时间,效果如图所示:

 
  1. // CommonUtils.ets
  2. datePickerDialog(dateCallback: Function) {
  3. DatePickerDialog.show({
  4. // 开始时间
  5. start: new Date(CommonConstants.START_TIME),
  6. // 结束时间
  7. end: new Date(),
  8. // 当前选中时间
  9. selected: new Date(CommonConstants.SELECT_TIME),
  10. // 是否显示农历
  11. lunar: false,
  12. onAccept: (value: DatePickerResult) => {
  13. let year: number = Number(value.year);
  14. let month: number = Number(value.month) + CommonConstants.PLUS_ONE;
  15. let day: number = Number(value.day);
  16. let birthdate: string = this.getBirthDateValue(year, month, day);
  17. dateCallback(birthdate);
  18. }
  19. });
  20. }
  21. // 获取出生日期值
  22. getBirthDateValue(year: number, month: number, day: number): string {
  23. let birthdate: string = `${year}${CommonConstants.DATE_YEAR}${month}` +
  24. `${CommonConstants.DATE_MONTH}${day}${CommonConstants.DATE_DAY}`;
  25. return birthdate;
  26. }
  27. // HomePage.ets
  28. build() {
  29. Column() {
  30. ...
  31. TextCommonWidget({
  32. textImage: $r('app.media.ic_birthdate'),
  33. title: $r('app.string.title_birthdate'),
  34. content: $birthdate,
  35. onItemClick: () => {
  36. CommonUtils.datePickerDialog((birthValue: string) => {
  37. this.birthdate = birthValue;
  38. });
  39. }
  40. })
  41. ...
  42. }
  43. ...
  44. }

文本滑动选择器弹窗

点击性别选项,通过CommonUtils.textPickerDialog方法弹出性别选择器弹窗,根据需要选择相应性别,效果如图所示:

 
  1. // CommonUtils.ets
  2. textPickerDialog(sexArray: Resource, sexCallback: Function) {
  3. ...
  4. TextPickerDialog.show({
  5. range: sexArray,
  6. selected: 0,
  7. onAccept: (result: TextPickerResult) => {
  8. sexCallback(result.value);
  9. },
  10. onCancel: () => {
  11. ...
  12. }
  13. });
  14. }
  15. // HomePage.ets
  16. build() {
  17. Column() {
  18. ...
  19. TextCommonWidget({
  20. textImage: $r('app.media.ic_sex'),
  21. title: $r('app.string.title_sex'),
  22. content: $sex,
  23. onItemClick: () => {
  24. CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {
  25. this.sex = sexValue;
  26. });
  27. }
  28. })
  29. ...
  30. }
  31. ...
  32. }

自定义弹窗

点击兴趣爱好选项,通过customDialogController.open方法弹出自定义弹窗,根据需要选择相应的兴趣爱好,效果如图所示:

在view目录下,点击鼠标右键 > New > ArkTS File,新建一个ArkTS文件,然后命名为CustomDialogWidget子组件。

在CustomDialogWidget的aboutToAppear方法,通过manager.getStringArrayValue方法获取本地资源数据进行初始化。

  1. // CustomDialogWidget.ets
  2. @State hobbyItems: HobbyItem[] = [];
  3. ...
  4. aboutToAppear() {
  5. let context: Context = getContext(this);
  6. if (CommonUtils.isEmpty(context) || CommonUtils.isEmpty(context.resourceManager)) {
  7. Logger.error(CommonConstants.TAG_CUSTOM, 'context or resourceManager is null');
  8. return;
  9. }
  10. let manager = context.resourceManager;
  11. manager.getStringArrayValue($r('app.strarray.hobbies_data').id, (error, hobbyArray) => {
  12. if (!CommonUtils.isEmpty(error)) {
  13. Logger.error(CommonConstants.TAG_CUSTOM, 'error = ' + JSON.stringify(error));
  14. } else {
  15. hobbyArray.forEach((hobby: string) => {
  16. let hobbyItem = new HobbyItem();
  17. hobbyItem.label = hobby;
  18. hobbyItem.isChecked = false;
  19. this.hobbyItems.push(hobbyItem);
  20. });
  21. }
  22. });
  23. }

当用户点击确定按钮时,通过setHobbiesValue方法处理自定义弹窗选项结果。

  1. // CustomDialogWidget.ets
  2. @State hobbyItems: HobbyItem[] = [];
  3. @Link hobbies: string;
  4. private controller?: CustomDialogController;
  5. // 处理自定义弹窗选项结果
  6. setHobbiesValue(hobbyItems: HobbyItem[]) {
  7. if (CommonUtils.isEmptyArr(hobbyItems)) {
  8. Logger.error(CommonConstants.TAG_HOME, 'hobbyItems length is 0');
  9. return;
  10. }
  11. let hobbiesText: string = '';
  12. hobbiesText = hobbyItems.filter((isCheckItem: HobbyItem) => isCheckItem?.isChecked)
  13. .map<string>((checkedItem: HobbyItem) => {
  14. return checkedItem.label!;
  15. })
  16. .join(CommonConstants.COMMA);
  17. if (hobbiesText.length > 0) {
  18. this.hobbies = hobbiesText;
  19. }
  20. }
  21. build() {
  22. Column() {
  23. ...
  24. Row() {
  25. Button($r('app.string.cancel_button'))
  26. .dialogButtonStyle()
  27. .onClick(() => {
  28. this.controller?.close();
  29. })
  30. Blank()
  31. ...
  32. Button($r('app.string.definite_button'))
  33. .dialogButtonStyle()
  34. .onClick(() => {
  35. this.setHobbiesValue(this.hobbyItems);
  36. this.controller?.close();
  37. })
  38. }
  39. }
  40. ...
  41. }
  42. @Extend(Button) function dialogButtonStyle() {
  43. ....
  44. }

通过@Link修饰的hobbies把值赋给HomePage的hobbies,然后hobbies刷新显示内容。

  1. // HomePage.ets
  2. @State hobbies: string = '';
  3. customDialogController: CustomDialogController = new CustomDialogController({
  4. builder: CustomDialogWidget({
  5. hobbies: $hobbies
  6. }),
  7. alignment: DialogAlignment.Bottom,
  8. customStyle: true,
  9. offset: {
  10. dx: 0,
  11. dy: CommonConstants.DY_OFFSET
  12. }
  13. });
  14. build() {
  15. Column() {
  16. ...
  17. TextCommonWidget({
  18. textImage: $r('app.media.ic_hobbies'),
  19. title: $r('app.string.title_hobbies'),
  20. content: $hobbies,
  21. onItemClick: () => {
  22. // 打开自定义弹窗
  23. this.customDialogController.open();
  24. }
  25. })
  26. }
  27. ...
  28. }

总结

您已经完成了本次Codelab的学习,并了解到以下知识点:

  1. 使用CustomDialogController实现自定义弹窗。
  2. 使用AlertDialog实现警告弹窗。
  3. 使用DatePickerDialog实现日期滑动选择弹窗。
  4. 使用TextPickerDialog实现文本滑动选择弹窗。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/259183
推荐阅读
相关标签
  

闽ICP备14008679号