【梅科尔工作室】从API9到API20工程适配:自定义弹窗信息展示

前言:环境要求

要求 项目 版本/型号
软件 DevEco Studio DevEco Studio 6
OpenHarmony SDK API version 20
硬件 开发板 润和RK3568开发板
OpenHarmony系统 6.0.0.47 Release

创建仓库获取案例

  1. 在atomgit自己的组织下创建仓库,并将仓库下载到本地
  2. 下载题目文件,将下载得到的题目文件复制到仓库文件中,替换原有文件

创建仓库

  1. 打开该路径下的终端,依次输入以下代码进行上传
git add .
git commit -m "V1.0上传"
git push origin main

迁移

使用DevEco Studio打开对应工程,点击通知,按下发图片操作即可

迁移步骤1
迁移步骤2


修改为API20

1. 下载API20 SDK

下载API20 SDK

2. 修改对应路径下代码

修改 entry/build-profile.json5项目/build-profile.json5,见下图修改即可

修改entry配置
修改项目配置


新接口替换旧接口

修改 DialogPage.ets 中老接口为新接口,查询鸿蒙开发者官网开发文档即可

//import UIAbility from '@ohos.app.ability.UIAbility';
import { UIAbility } from '@kit.AbilityKit';

//import hilog from '@ohos.hilog';
import { hilog } from '@kit.PerformanceAnalysisKit';

//import window from '@ohos.window';
import { window } from '@kit.ArkUI';

验证升级后功能完整性

升级后验证功能,自定义弹窗效果如图所示

自定义弹窗效果


个性化功能添加

  • 基础图文弹窗,设置居中、大小调节
  • 交互式链式弹窗(在一个弹窗中触发另一个新弹窗)
  • 自动消失的提示弹窗

DAYU200升级OpenHarmony 6.0

安装驱动

驱动安装1
驱动安装2

给DAYU200烧录镜像源

  1. 去官网下载DAYU200的镜像源

    网址:https://ci.openharmony.cn/workbench/cicd/dailybuild/dailylist

    下载镜像

  2. 导入镜像源配置。注意:需要更换镜像实际的路径位置

    导入配置1
    导入配置2

  3. 按住VOL-/RECOVERY 按键(图中标注的①号键)不松开 1.5秒时按一次RESET 按钮(图中标注的②号键)。

    按键操作

  4. 此时烧录工具显示"发现一个LOADER设备",说明进入了烧写模式。松开按键,点击"执行"按钮进行烧录。如果烧写成功,在工具界面右侧会显示下载完成

    烧录过程
    烧录完成


大赛开发流程

代码结构解读

相较于基础版本,本次升级新增了两个自定义弹窗组件 New1Dialog.etsNew2Dialog.ets,并对主页面 DialogPage.ets 进行了逻辑增强,以支持更复杂的弹窗交互。

完整的代码结构如下:

├──entry/src/main/ets               // ArkTS源代码目录
 │  ├──common
 │  │  ├──constants
 │  │  │  └──StyleConstants.ets      // 全局样式常量
 │  │  └──utils
 │  │     └──Logger.ets              // 日志工具类
 │  ├──entryability
 │  │  └──EntryAbility.ts            // 程序入口
 │  ├──pages
 │  │  └──DialogPage.ets             // 核心交互页面
 │  └──view
 │     ├──ConfirmDialog.ets          // 确认/取消弹窗(升级)
 │     ├──CustomAlertDialog.ets      // 基础自定义弹窗
 │     ├──New1Dialog.ets             // 【新增】链式交互弹窗
 │     └──New2Dialog.ets             // 【新增】自动消失提示弹窗
 └──entry/src/main/resources         // 资源文件目录

界面效果

界面1
界面2
界面3
界面4
界面5


核心实现详解

1. 弹窗调度中心:DialogPage.ets

DialogPage.ets 作为主页面,不仅是UI的容器,更是所有弹窗的"调度中心"。我们在这里初始化了多个 CustomDialogController 实例,每个实例都与一个特定的自定义弹窗组件绑定。

1.1 初始化弹窗控制器

我们为本次新增的两个弹窗 CustomAlertNewDialogCustomAlertNew2Dialog 创建了对应的控制器 dialogCustomAlertNewDialogdialogCustomAlertNew2Dialog

// DialogPage.ets

// ...导入其他组件
import CustomAlertNewDialog from '../view/New1Dialog';
import CustomAlertNew2Dialog from '../view/New2Dialog';

@Entry
@Component
struct DialogPage {
  // ...已有的控制器

  // 新增:用于链式弹窗的控制器
  dialogCustomAlertNewDialog: CustomDialogController = new CustomDialogController({
    builder: CustomAlertNewDialog({ cancel: this.onCancel, confirm: this.onAccept }),
    cancel: this.existApp,
    autoCancel: true,
    alignment: DialogAlignment.Center,
    customStyle: true
  });

  // 新增:用于自动消失弹窗的控制器
  dialogCustomAlertNew2Dialog: CustomDialogController = new CustomDialogController({
    builder: CustomAlertNew2Dialog({ cancel: this.onCancel, confirm: this.onAccept }),
    cancel: this.existApp,
    autoCancel: true,
    alignment: DialogAlignment.Center,
    customStyle: true
  });

  // ...其他方法
}
1.2 实现链式弹窗逻辑

链式弹窗是本次升级的核心亮点。我们通过改造 ConfirmDialog 的确认回调函数,实现了关闭当前弹窗后,延时开启一个新弹窗的效果。

// DialogPage.ets

struct DialogPage {
  // 定义一个新方法,用于关闭旧弹窗并打开新弹窗
  NewDialog = (): void => {
    this.dialogControllerExample.close(); // 关闭当前的ConfirmDialog
    setTimeout(() => {
        this.dialogCustomAlertNewDialog.open(); // 延时100ms后打开New1Dialog
    }, 100);
  };

  // 将NewDialog方法作为回调传递给ConfirmDialog
  dialogControllerExample: CustomDialogController = new CustomDialogController({
    builder: ConfirmDialog({ cancel: this.onCancel, confirm: this.NewDialog}), // 此处是关键
    // ...其他配置
  });

  // ...
}
1.3 实现自动消失弹窗

通过 setTimeout,我们可以轻松实现一个延时任务,在弹窗打开2秒后自动调用其 close 方法。

// DialogPage.ets

// ...
// 页面中的触发按钮
Button($r('app.string.customization_dialog'))
  .onClick(() => {
    this.dialogCustomAlertNew2Dialog.open(); // 打开弹窗
    setTimeout(() => {
      this.dialogCustomAlertNew2Dialog.close(); // 2秒后关闭
    }, 2000);
  })
// ...

2. 链式交互弹窗:New1Dialog.ets

这个组件本身是一个标准的自定义弹窗,其特殊之处在于它是由另一个弹窗触发的。这展示了 CustomDialogController 的灵活性和强大的流程控制能力。

// New1Dialog.ets

import StyleConstants from '../common/constants/StyleConstants';

@CustomDialog
export default struct CustomAlertNewDialog {
  controller?: CustomDialogController;
  cancel: () => void = () => {};
  confirm: () => void = () => {};

  build() {
    Column() {
      // 弹窗内容:包含一张图片和文本
      Row() {
        Image($rawfile('shuju.png')) // 展示图片资源
          .width(250)
          .height(250)
      }
      Text($r('app.string.dialog_2_message'))
        .fontSize($r('app.float.font_size_normal'))
        .margin({ top: $r('app.float.icon_margin_top') })

      Flex({ justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
        Button($r('app.string.cancel_1_txt'))
          .onClick(() => {
            this.cancel();
            if (this.controller) {
              this.controller.close(); // 点击后关闭自身
            }
          })
          // ...按钮样式
      }
      .margin({ top: $r('app.float.dialog_button_margin_top') })
    }
    // ...弹窗统一样式
    .width(StyleConstants.CUSTOM_DIALOG_WIDTH)
    .height(StyleConstants.DIALOG_HEIGHT_1)
    .backgroundColor($r('app.color.start_window_background'))
    .borderRadius($r('app.float.dialog_border_radius'))
  }
}

3. 自动消失提示:New2Dialog.ets

这是一个极简的提示弹窗,用于向用户展示简短信息后自动消失,提升用户体验。其实现非常简洁,核心逻辑在于外部的 setTimeout 控制。

// New2Dialog.ets

import StyleConstants from '../common/constants/StyleConstants';

@CustomDialog
export default struct CustomAlertNewDialog {
  controller?: CustomDialogController;
  cancel: () => void = () => {};
  confirm: () => void = () => {};

  build() {
    Column() {
      // 只包含一个提示文本
      Text($r('app.string.dialog_3_message'))
        .fontSize($r('app.float.font_size_normal'))
        .margin({ top: $r('app.float.icon_margin_top') })
    }
    // ...弹窗统一样式,定义了较小的高度
    .width(StyleConstants.CUSTOM_DIALOG_WIDTH)
    .height(StyleConstants.DIALOG_HEIGHT_2)
    .backgroundColor($r('app.color.start_window_background'))
    .borderRadius($r('app.float.dialog_border_radius'))
  }
}

总结

AtomGit仓库地址: https://atomgit.com/MakerStudio/HM_Custom_pop-up_window.git

通过本次的案例升级,我们不仅巩固了使用 @CustomDialogCustomDialogController 创建和管理自定义弹窗的基础知识,更进一步探索了它们在复杂交互场景下的高级应用。

核心知识点总结

  1. 模块化弹窗设计:将每个弹窗封装成独立的组件,便于复用和管理
  2. 控制器集中管理:在页面级统一初始化和管理所有弹窗的 CustomDialogController,使弹窗的调用和生命周期控制更加清晰
  3. 回调函数实现复杂交互:通过将函数作为参数传递给弹窗组件,可以构建出灵活的、可定制的交互逻辑,如本次实现的链式弹窗
  4. 结合异步任务控制弹窗行为:利用 setTimeout 等异步API,可以实现对弹窗状态的延时控制,如自动关闭,为优化用户体验提供了更多可能性

参考资料

  • 华为开发者联盟鸿蒙开发文档:https://developer.harmonyos.com/cn/docs
  • ArkTS开发语言规范:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-based-syntax-0000001127164111
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐