当前位置:   article > 正文

OpenHarmony开发实战:构建多种样式弹窗(ArkTS)_openharmony文本框

openharmony文本框

介绍

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

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

相关概念

环境搭建

软件要求

  • DevEco Studio版本:DevEco Studio 3.1 Release。
  • OpenHarmony SDK版本:API version 9。

硬件要求

环境搭建

完成本篇Codelab我们首先要完成开发环境的搭建,本示例以RK3568开发板为例,参照以下步骤进行:

  1. 获取OpenHarmony系统版本:标准系统解决方案(二进制)。以3.2 Release版本为例:

  2. 搭建烧录环境。

    1. 完成DevEco Device Tool的安装
    2. 完成RK3568开发板的烧录
  3. 搭建开发环境。

    1. 开始前请参考工具准备,完成DevEco Studio的安装和开发环境配置。
    2. 开发环境配置完成后,请参考使用工程向导创建工程(模板选择“Empty Ability”)。
    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. │ └──HobbyModel.ets // 兴趣爱好model类
  18. └──entry/src/main/resources // 资源文件目录

构建主页面

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

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

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

  2. 文本输入框抽取成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)
    11. ...
    12. TextInput({ placeholder: this.hintText })
    13. ...
    14. }
    15. ...
    16. }
    17. }
  3. 文本布局抽取成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: () => void = () => {};
    12. build() {
    13. Row() {
    14. Image(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. }
  4. 在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. build() {
    9. Column() {
    10. ...
    11. TextInputWeight({
    12. inputImage: $r("app.media.ic_nickname"),
    13. hintText: $r("app.string.text_input_hint")
    14. })
    15. TextCommonWeight({
    16. textImage: $r("app.media.ic_birthdate"),
    17. title: $r("app.string.title_birthdate"),
    18. content: $birthdate,
    19. onItemClick: () => {
    20. CommonUtils.datePickerDialog((birthValue: string) => {
    21. this.birthdate = birthValue;
    22. });
    23. }
    24. })
    25. TextCommonWeight({
    26. textImage: $r("app.media.ic_sex"),
    27. title: $r("app.string.title_sex"),
    28. content: $sex,
    29. onItemClick: () => {
    30. CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {
    31. this.sex = sexValue;
    32. });
    33. }
    34. })
    35. TextInputWeight({
    36. inputImage: $r("app.media.ic_signature"),
    37. hintText: $r("app.string.text_input_signature")
    38. })
    39. TextCommonWeight({
    40. textImage: $r("app.media.ic_hobbies"),
    41. title: $r("app.string.title_hobbies"),
    42. content: $hobbies,
    43. onItemClick: () => {
    44. this.customDialogController.open();
    45. }
    46. })
    47. }
    48. ...
    49. }
    50. }

警告弹窗

点击主页面左上角返回按钮,通过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. ...
  15. },
  16. secondaryButton: {
  17. // 退出应用
  18. context.terminateSelf();
  19. ...
  20. }
  21. });
  22. }

日期滑动选择器弹窗

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

  1. // CommonUtils.ets
  2. datePickerDialog(dateCallback) {
  3. DatePickerDialog.show({
  4. // 开始时间
  5. start: new Date(CommonConstants.START_TIME),
  6. // 结束时间
  7. end: new Date(CommonConstants.END_TIME),
  8. // 当前选中时间
  9. selected: new Date(),
  10. // 是否显示农历
  11. lunar: false,
  12. onAccept: (value: DatePickerResult) => {
  13. let year = value.year as number;
  14. let month = value.month as number + CommonConstants.PLUS_ONE;
  15. let day = value.day as number;
  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. TextCommonWeight({
  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: (sexValue: string) => void) {
  3. TextPickerDialog.show({
  4. range: sexArray,
  5. selected: 0,
  6. onAccept: (result: TextPickerResult) => {
  7. sexCallback(result.value);
  8. },
  9. onCancel: () => {
  10. ...
  11. }
  12. });
  13. }
  14. // HomePage.ets
  15. build() {
  16. Column() {
  17. ...
  18. TextCommonWeight({
  19. textImage: $r('app.media.ic_sex'),
  20. title: $r("app.string.title_sex"),
  21. content: $sex,
  22. onItemClick: () => {
  23. CommonUtils.textPickerDialog(this.sexArray, (sexValue: string) => {
  24. this.sex= sexValue;
  25. });
  26. }
  27. })
  28. ...
  29. }
  30. ...
  31. }

自定义弹窗

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

自定义弹窗实现分为以下步骤:

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

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

    1. // CustomDialogWeight.ets
    2. @State hobbyModels: HobbyModel[] = [];
    3. aboutToAppear() {
    4. let context: Context = getContext(this);
    5. if (CommonUtils.isEmpty(context) || CommonUtils.isEmpty(context.resourceManager)) {
    6. Logger.error(CommonConstants.TAG_CUSTOM, 'context or resourceManager is null');
    7. return;
    8. }
    9. let manager = context.resourceManager;
    10. manager.getStringArrayValue($r("app.strarray.hobbies_data").id, (error, hobbyArray) => {
    11. if (!CommonUtils.isEmpty(error)) {
    12. Logger.error(CommonConstants.TAG_CUSTOM, 'error = ' + JSON.stringify(error));
    13. } else {
    14. hobbyArray.forEach((hobbyItem: string) => {
    15. let hobbyModel = new HobbyModel();
    16. hobbyModel.label = hobbyItem;
    17. hobbyModel.isChecked = false;
    18. this.hobbyModels.push(hobbyModel);
    19. });
    20. }
    21. });
    22. }
  3. 当用户点击确定按钮时,通过setHobbiesValue方法处理自定义弹窗选项结果。

    1. // CustomDialogWeight.ets
    2. @State hobbyModels: HobbyModel[] = [];
    3. @Link hobbies: string;
    4. // 处理自定义弹窗选项结果
    5. setHobbiesValue(hobbyModels: HobbyModel[]) {
    6. if (CommonUtils.isEmptyArr(hobbyModels)) {
    7. Logger.error(CommonConstants.TAG_CUSTOM, 'hobbyModels length is 0');
    8. return;
    9. }
    10. let hobbiesText: string = '';
    11. hobbiesText = hobbyModels.filter((isCheckItem: HobbyModel) => isCheckItem?.isChecked)
    12. .map((checkedItem: HobbyModel) => {
    13. return checkedItem.label;
    14. })
    15. .join(CommonConstants.COMMA);
    16. if (hobbiesText.length > 0) {
    17. this.hobbies = hobbiesText;
    18. }
    19. }
    20. build() {
    21. Column() {
    22. ...
    23. Row() {
    24. Button($r('app.string.cancel_button'))
    25. .dialogButtonStyle()
    26. .onClick(() => {
    27. this.controller.close();
    28. })
    29. Blank()
    30. ...
    31. Button($r('app.string.definite_button'))
    32. .dialogButtonStyle()
    33. .onClick(() => {
    34. this.setHobbiesValue(this.hobbyModels);
    35. this.controller.close();
    36. })
    37. }
    38. }
    39. ...
    40. }
    41. @Extend(Button) function dialogButtonStyle() {
    42. ....
    43. }
  4. 通过@Link修饰的hobbies把值赋给HomePage的hobbies,然后hobbies刷新显示内容。

    1. // HomePage.ets
    2. @State hobbies: string = '';
    3. customDialogController: CustomDialogController = new CustomDialogController({
    4. builder: CustomDialogComponent({
    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. TextCommonWeight({
    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. }

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料

 获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

 有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/659403
推荐阅读
相关标签
  

闽ICP备14008679号