OpenHarmony实战开发-如何使用不同的弹窗。

567 篇文章 1 订阅
555 篇文章 0 订阅

场景说明

应用中经常用到弹窗,比如警告弹窗、日期选择弹窗、文本选择弹窗以及其他自定义弹窗等等。本例将为大家介绍如何使用不同的弹窗。

效果呈现

本例最终效果如下:
在这里插入图片描述
示例中共涉及四类弹窗:

  • 警告弹窗:提示信息尚未保存。
  • 日期滑动选择器弹窗:选择出生日期。
  • 文本滑动选择器弹窗:选择性别。
  • 自定义弹窗:填写兴趣爱好。

说明: 自定义弹窗可以根据业务需要自行定义弹窗的形式和内容,比如文本输入、单选、多选等等,本例以文本输入为例进行介绍。

运行环境

本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:

  • IDE: DevEco Studio 3.1 Release
  • SDK: Ohos_sdk_public 3.2.12.5(APIVersion 9 Release)

实现思路

本例中涉及的4类弹窗及实现方案如下:

  • 警告弹窗:使用AlertDialog实现。
  • 日期滑动选择器弹窗:使用DatePickerDialog实现。
  • 文本滑动选择器弹窗:使用TextPickerDialog实现。
  • 自定义弹窗:使用CustomDialogController实现。

开发步骤

由于本例重点讲解对话框的使用,所以开发步骤会着重讲解相关实现,不相关的内容不做介绍,全量代码可参考完整代码章节。

1.首先,使用AlertDialog实现警告弹窗。

通过message参数设置告警信息,alignment设置弹窗在界面中垂直方向的对齐方式;通过primaryButton和secondaryButton添加按钮。 具体代码如下:

alertDialog(context: Context.UIAbilityContext) {
  AlertDialog.show({
    // 通过message设置告警信息
    message: '当前数据未保存,是否确认离开?',
    // 通过alignment设置弹窗在界面垂直方向的对齐方式,此处设置为底部对齐
    alignment: DialogAlignment.Bottom,
    // 通过offset设置基于对齐位置的便宜量
    offset: {
      dx: 0,
      dy: -20
    },
    // 弹窗中左起第一个按钮
    primaryButton: {
      value: '取消',
      action: () => {
        console.info('Callback cancel button is clicked');
      }
    },
    // 弹窗中左起第二个按钮
    secondaryButton: {
      value: '确定',
      action: () => {
        // Exiting the app.
        context.terminateSelf();
        console.info('Callback definite button is clicked');
      }
    }
  });
}

2.使用DatePickerDialog实现日期滑动选择器弹窗。

通过start和end分别设置日期区间的起始时间和末尾时间;通过lunar设置使用农历还是阳历;使用onAccept监听选择的日期,本例中通过变量selectedDate将选中的日期设置给参数selected,这样弹窗弹出时的日期就默认为上次选中的日期。 具体代码如下:

datePickerDialog(dateCallback) {
  DatePickerDialog.show({
    start: new Date('1900-1-1'),
    end: new Date('2100-1-1'),
    // 通过变量selectedDate将选中的日期设置给参数selected
    selected: this.selectedDate,
    lunar: false,
    // 使用onAccept监听选择的日期
    onAccept: (value: DatePickerResult) => {
      let year = value.year;
      let month = value.month + 1;
      let day = value.day;
      let birthdate: string = this.getBirthDateValue(year, month, day);
      // 通过setFullYear将选中的日期传递给变量selectedDate
      this.selectedDate.setFullYear(value.year, value.month, value.day)
      // 返回选中的日期
      dateCallback(birthdate);
    }
  });
}

3.使用TextPickerDialog实现文本滑动选择器弹窗。

通过range设置文本选择项,使用onAccept监听选择的文本项,本例中通过变量selectedGender将选中的性别的索引设置给参数selected,这样弹窗弹出时的性别就默认为上次选中的性别。 具体代码如下:

textPickerDialog(sexArray: Resource, sexCallback) {
  // 判断文本项的列表是否为空
  if (this.isEmptyArr(sexArray)) {
    console.error('sex is null');
    return;
  }
  TextPickerDialog.show({
    // 通过range设置文本选择项
    range: sexArray,
    // 通过变量selectedGender将选中的性别的索引设置给参数selected
    selected: this.selectedGender,
    // 使用onAccept监听选择的文本项
    onAccept: (result: TextPickerResult) => {
      sexCallback(result.value);
      // 获取选中项的索引
      this.selectedGender = result.index
    },
    onCancel: () => {
      console.info('TextPickerDialog onCancel');
    }
  });
}

4.使用CustomDialogController实现自定义弹窗。

当现有弹窗不能满足业务诉求时,开发者可以自行设计弹窗的样式。在实现自定义弹窗时,需要将弹窗的UI放在被@CustomDialog修饰的自定义组件中,然后使用CustomDialogController的实例来控制弹窗的弹出和关闭。 具体代码如下:

// 使用@CustomDialog修饰自定义弹窗
@CustomDialog
struct CustomDialogFrame{
  ...
  // 定义CustomDialogController
  controller: CustomDialogController

  build(){
    Column() {
      Text('兴趣爱好').fontSize(20).margin({ top: 10, bottom: 10 })
      TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
        .onChange((value: string) => {
          this.textValue = value
        })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('取消')
          .onClick(() => {
            // 点击‘取消’,弹窗关闭
            this.controller.close()
          })
          .backgroundColor('')
          .fontColor('#007DFF')
        Button('保存')
          .onClick(() => {
            this.inputValue = this.textValue
            // 点击‘保存’,弹窗关闭
            this.controller.close()
          })
          .backgroundColor(0xffffff)
          .fontColor('#007DFF')
      }.margin({ bottom: 10 })
    }.justifyContent(FlexAlign.Start)
  }
}
...
  // 实例化自定义弹窗
  customDialogController: CustomDialogController = new CustomDialogController({
    // 使用上文创建的自定义弹窗进行实例化
    builder: CustomDialogFrame({
      textValue: $textValue,
      inputValue: $inputValue
    }),
    alignment: DialogAlignment.Bottom,
    offset: {
      dx: 0,
      dy: -20
    }
  });
...

完整代码

本例完整代码如下:

import Context from '@ohos.app.ability.common';
import hilog from '@ohos.hilog';

@Component
struct TextFrame{
  @Link content: string;
  private textImage:Resource;
  private text:string;
  onTextClick:()=>void;

  build(){
    Row(){
      Image(this.textImage)
        .width(24)
        .height(24)
        .margin({left:12})
      Text(this.text)
        .fontSize(16)
        .margin({ left:12 })
        .height(24)
      Text(this.content)
        .fontSize(16)
        .textAlign(TextAlign.End)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(1)
        .margin({
          left: 16,
          right: 7
        })
        .layoutWeight(1)
        .width('100%')
      Image($r('app.media.ic_arrow'))
        .width(12)
        .height(24)
        .margin({ right: 14 })
    }
    .margin({ top: 24 })
    .borderRadius(24)
    .backgroundColor(Color.White)
    .width('93.3%')
    .height(64)
    .onClick(this.onTextClick)
  }
}

@Component
struct InputFrame{
  private inputImage: Resource;
  private hintText: string;

  build(){
    Row() {
      Image(this.inputImage)
        .width(24)
        .height(24)
        .margin({ left: 12 })
      TextInput({ placeholder: this.hintText })
        .fontSize(16)
        .padding({ left: 12 })
        .placeholderColor('#99000000')
        .backgroundColor(Color.White)
        .fontWeight(FontWeight.Normal)
        .fontStyle(FontStyle.Normal)
        .fontColor(Color.Black)
        .margin({ right: 32 })
        .layoutWeight(1)
        .height(48)
    }
    .margin({ top: 24 })
    .borderRadius(24)
    .backgroundColor(Color.White)
    .width('93.3%')
    .height(64)
  }
}

@CustomDialog
struct CustomDialogFrame{
  @Link textValue: string
  @Link inputValue: string
  controller: CustomDialogController

  build(){
    Column() {
      Text('兴趣爱好').fontSize(20).margin({ top: 10, bottom: 10 })
      TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%')
        .onChange((value: string) => {
          this.textValue = value
        })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('取消')
          .onClick(() => {
            this.controller.close()
          }).backgroundColor('').fontColor('#007DFF')
        Button('保存')
          .onClick(() => {
            this.inputValue = this.textValue
            this.controller.close()
          }).backgroundColor(0xffffff).fontColor('#007DFF')
      }.margin({ bottom: 10 })
    }.justifyContent(FlexAlign.Start)
  }
}

@Entry
@Component
struct Index {
  @State birthdate: string = '';
  @State sex: string = '';
  @State textValue: string = '';
  @State inputValue: string = '';
  selectedDate: Date = new Date("2010-1-1")
  selectedGender:number = 0
  private sexArray: Resource = $r('app.strarray.sex_array');
  customDialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogFrame({
      textValue: $textValue,
      inputValue: $inputValue
    }),
    alignment: DialogAlignment.Bottom,
    offset: {
      dx: 0,
      dy: -20
    }
  });

  alertDialog(context: Context.UIAbilityContext) {
    AlertDialog.show({
      message: '当前数据未保存,是否确认离开?',
      alignment: DialogAlignment.Bottom,
      offset: {
        dx: 0,
        dy: -20
      },
      primaryButton: {
        value: '取消',
        action: () => {
          console.info('Callback cancel button is clicked');
        }
      },
      secondaryButton: {
        value: '确定',
        action: () => {
          // Exiting the app.
          context.terminateSelf();
          console.info('Callback definite button is clicked');
        }
      }
    });
  }

  datePickerDialog(dateCallback) {
    DatePickerDialog.show({
      start: new Date('1900-1-1'),
      end: new Date('2100-1-1'),
      selected: this.selectedDate,
      lunar: false,
      onAccept: (value: DatePickerResult) => {
        let year = value.year;
        let month = value.month + 1;
        let day = value.day;
        let birthdate: string = this.getBirthDateValue(year, month, day);
        this.selectedDate.setFullYear(value.year, value.month, value.day)
        dateCallback(birthdate);
      }
    });
  }

  textPickerDialog(sexArray: Resource, sexCallback) {
    if (this.isEmptyArr(sexArray)) {
      console.error('sex is null');
      return;
    }
    TextPickerDialog.show({
      range: sexArray,
      selected: this.selectedGender,
      onAccept: (result: TextPickerResult) => {
        sexCallback(result.value);
        this.selectedGender = result.index
      },
      onCancel: () => {
        console.info('TextPickerDialog onCancel');
      }
    });
  }

  getBirthDateValue(year: number, month: number, day: number): string {
    let birthdate: string = `${year}${'年'}${month}` +
    `${'月'}${day}${'日'}`;
    return birthdate;
  }

  isEmpty(obj): boolean {
    return obj === undefined || obj === null || obj === '';
  }

  isEmptyArr(array): boolean {
    return this.isEmpty(array) || array.length === 0;
  }

  build() {
    Row() {
      Column() {
        Row(){
          Image($r('app.media.ic_back'))
            .width(26)
            .height(26)
            .alignSelf(ItemAlign.Start)
            .margin({
              left: '7.2%',
              top: 19
            })
            .onClick(() => {
              let context = getContext(this) as Context.UIAbilityContext;
              this.alertDialog(context);
            })
          Text('个人信息')
            .fontColor(Color.Black)
            .fontSize(20)
            .margin({ top: 20,left:20 })
            .alignSelf(ItemAlign.Center)
        }.width('100%')
        Image($r('app.media.ic_avatar'))
          .width(56)
          .height(56)
          .alignSelf(ItemAlign.Center)
          .margin({ top: '5.5%' })
        Text('头像')
          .fontColor(Color.Black)
          .fontSize(16)
          .margin({ top: '2.1%' })
          .alignSelf(ItemAlign.Center)
        InputFrame({
          inputImage: $r('app.media.ic_nickname'),
          hintText: '昵称'
        })
        TextFrame({
          textImage: $r('app.media.ic_birthdate'),
          text: '出生日期',
          content: $birthdate,
          onTextClick: () => {
            this.datePickerDialog((birthValue: string) => {
              this.birthdate = birthValue;
            });
          }
        })
        TextFrame({
          textImage: $r('app.media.ic_sex'),
          text: '性别',
          content: $sex,
          onTextClick: () => {
            this.textPickerDialog(this.sexArray, (sexValue: string) => {
              this.sex = sexValue;
            });
          }
        })
        InputFrame({
          inputImage: $r('app.media.ic_signature'),
          hintText: '个性签名'
        })
        TextFrame({
          textImage: $r('app.media.ic_hobbies'),
          text: '兴趣爱好',
          content: $textValue,
          onTextClick: () => {
            this.customDialogController.open();
          }
        })
      }
      .backgroundColor('#F5F5F5')
      .height('100%')
      .width('100%')
    }
    .height('100%')
  }
}

我这边特意整理了《鸿蒙语法ArkTS、TypeScript、ArkUI、实战开发视频教程》以及《鸿蒙生态应用开发白皮书V2.0PDF》《鸿蒙开发学习手册》(共计890页)鸿蒙开发资料等…希望对大家有所帮助:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

鸿蒙语法ArkTS、TypeScript、ArkUI等…视频教程:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

OpenHarmony APP开发教程步骤:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

鸿蒙生态应用开发白皮书V2.0PDF:https://docs.qq.com/doc/DZVVkRGRUd3pHSnFG

在这里插入图片描述

应用开发中级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

应用开发中高级就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

南北双向高工技能基础:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

全网首发-工业级 南向设备开发就业技术:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

在这里插入图片描述

《鸿蒙开发学习手册》:

如何快速入门:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.基本概念
2.构建第一个ArkTS应用
3.……

在这里插入图片描述

开发基础知识:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发:https://docs.qq.com/doc/DZVVBYlhuRkZQZlB3

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值