Bootstrap

【鸿蒙实战开发】HarmonyOS中如何实现零侵入弹窗

前言

不管在鸿蒙开发中还是在其他项目开发中,比如Android、iOS等其实弹窗都是必不可少的一个组件,在其他端中其实实现方式很多,也很优雅,代码零侵入。但是在鸿蒙开发中,其实跟网页开发实现方式差不多,弹窗基本会在布局中预先声明,在通过状态值来控制显示隐藏,当然也有非常厉害的可以把popup完全解耦出来。在鸿蒙中,因为生态还不够强大,很多东西还没有轮子,也没有可以找的资源,所以很多东西需要慢慢摸索。以下都以实现一个Loading举例:

1. 现有常见方案

常见的创建Loading弹窗有很多中,我只举例以下几种方案:

方案一

自定义一个Loading组件,在需要使用Loading的地方引入,在通过状态值控制显示隐藏

方案二

在需要Loading的界面根布局添加bindPopup属性,通过第一个参数来控制显示隐藏,当然也可以写在整个路由的根布局,通过全局状态参数来控制,这样比写在每一个界面还是好一点

方案三

自定义弹窗 CustomDialog,然后在需要弹窗的地方通过CustomDialogController控制器控制

方案四

通过创建子window方式创建
通过以上方案可以看出,每一种实现方式多儿不少都需要去改动原来的代码,这样使代码越来越复杂和杂乱,那有没有一种方案是代码零侵入,只需在调用的地方拉起弹窗呢?请接着往下看。

2. 零侵入方案

在声明式范式中,组件仅在build环节中被创建,开发者无法在其他生命周期阶段进行组件的创建,从而引起页面加载慢等问题。好在鸿蒙给出了解决方案UI动态操作,UI动态操作包含组件动态创建、卸载等相关操作。下面我们按照流程一步一步实现Loading弹窗。
创建自定义节点

export class PopupBean{

  /**
   * 进度提示
   */
  hint:string

  constructor(hint: string) {
    this.hint = hint
  }

}

@Builder
export function loadingBuilder(data: PopupBean) {
  Column() {
    LoadingProgress().width("80lpx").height("80lpx")
    Text(data.hint).fontColor("#999999").margin("10lpx").fontSize("28lpx")
  }
  .backgroundColor(Color.White)
  .padding("20lpx")
  .borderRadius("10lpx")
  .alignItems(HorizontalAlign.Center)
  .justifyContent(FlexAlign.Center)
}

注意:这里loadingBuilder中的参数要不没有,要不就需要自定义一个类,不能使用string、number等

显示自定义节点

import { ComponentContent, PromptAction, window } from '@kit.ArkUI';
import { PopupBean } from '自己定义的路径';
import { HashMap } from '@kit.ArkTS';

/**
 * 进度加载管理
 */
export class LoadingManager {
  private static instance: LoadingManager
  private popupHashMap: HashMap<PromptAction, ComponentContent<PopupBean>>[] = []

  private constructor() {
  }

  static getInstance(): LoadingManager {
    if (LoadingManager.instance == null) {
      LoadingManager.instance = new LoadingManager()
    }
    return LoadingManager.instance
  }

  /**
   * 加载中...
   * @param hint
   */
  loading(hint: string = "加载中...") {
    window.getLastWindow(getContext()).then((windowClass) => {
      const uiContext = windowClass.getUIContext()
      //这里去动态创建组件
      let loadingPopup = new ComponentContent(uiContext, wrapBuilder(loadingBuilder), new PopupBean(hint))
      //获取上下文中的PromptAction
      let promptAction = uiContext.getPromptAction()
      try {
        //存储数据,方便关闭弹窗使用
        let hashMap: HashMap<PromptAction, ComponentContent<PopupBean>> = new HashMap()
        hashMap.set(promptAction, loadingPopup)
        this.popupHashMap.push(hashMap)
        //打开弹窗,这里openCustomDialog第二个参数可以自定义,这里只是Demo就不过多介绍了
        promptAction.openCustomDialog(loadingPopup, {
          alignment: DialogAlignment.Center,
          isModal: false,
          autoCancel: true
        })
      } catch (e) {
        console.error(JSON.stringify(e))
      }
    })
  }

  /**
   * 关闭弹窗
   */
  dismiss() {
    window.getLastWindow(getContext()).then((windowClass) => {
      let size = this.popupHashMap.length
      if (size == 0) {
        return
      }
      let lastHashMap = this.popupHashMap[size - 1]
      this.closePopup(lastHashMap)
      this.popupHashMap.splice(size - 1, 1)
    })
  }

  /**
   * 关闭所有弹窗
   */
  dismissAll() {
    window.getLastWindow(getContext()).then((windowClass) => {
      this.popupHashMap.forEach((hashMap: HashMap<PromptAction, ComponentContent<PopupBean>>) => {
        this.closePopup(hashMap)
      })
      this.popupHashMap = []
    })
  }

  /**
   * 关闭弹窗
   * @param hashMap
   */
  private closePopup(hashMap: HashMap<PromptAction, ComponentContent<PopupBean>>) {
    hashMap.forEach((loadingPopup: ComponentContent<PopupBean>, promptAction: PromptAction) => {
      promptAction.closeCustomDialog(loadingPopup)
    })
  }
}

注意:这里关闭弹窗也需要在window.getLastWindow(getContext())中去执行,可以避免执行时序问题

导出组件

import { LoadingManager } from '自己定义的路径'
const Loading = LoadingManager.getInstance()

使用

import { Loading } from '自己定义的路径'
//自定义加载弹窗内容
Loading.loading("获取数据中...")
//使用默认加载弹窗内容
Loading.loading()
//关闭弹窗
Loading.dismiss()
//关闭所有弹窗
Loading.dismissAll()

至此,动态创建组件弹窗就完了,没有几句代码,按照项目要求自己实现效果就行了。

3.直接使用

ohpm i @chinalike/popup

写在最后

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

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

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

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

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

在这里插入图片描述

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

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

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

在这里插入图片描述

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

在这里插入图片描述

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

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

在这里插入图片描述

《鸿蒙开发基础》

●ArkTS语言
●安装DevEco Studio
●运用你的第一个ArkTS应用
●ArkUI声明式UI开发
.……
在这里插入图片描述

《鸿蒙开发进阶》

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

《鸿蒙进阶实战》

●ArkTS实践
●UIAbility应用
●网络案例
……
在这里插入图片描述

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

;