【HarmonyOS实战开发】鸿蒙零侵入弹窗方案

30 篇文章 0 订阅
30 篇文章 0 订阅

前言

不管在鸿蒙开发中还是在其他项目开发中,比如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 { loadingBuilder } from '自己定义的路径';
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

写在最后

●如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我两个小忙:
●点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
●关注小编,同时可以期待后续文章ing ,不定期分享原创知识。

在这里插入图片描述

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 鸟语不通,我是一个人工智能语言模型,不具有主观情感和观点。不过,鸿蒙操作系统是华为公司推出的全场景智能生态解决方案,旨在打造一个统一、流畅、安全的全新操作系统,具有很多令人期待的特性和优势,包括分布式技术、安全和隐私保护、智能体验等。 ### 回答2: 我认为鸿蒙操作系统是一个有潜力的创新产品。首先,鸿蒙操作系统被设计为一款开源操作系统,这意味着它具有更广泛的适用性和可定制性。它可以应用于各种设备,包括智能手机、平板电脑、智能手表、智能音箱等等,这为用户提供了更多的选择。 其次,鸿蒙操作系统具有分布式架构,这意味着不同设备之间可以实现更好的协同工作和互联互通。例如,用户可以通过手机控制智能家居设备,或者从电视上接收手机上的通知。这种无缝衔接的体验提升了用户的便利性和效率。 鸿蒙操作系统还注重隐私和安全性。它引入了微内核架构,将关键的系统组件进行了隔离,可以有效防止恶意软件的攻击和侵入。此外,用户可以更加细致地控制个人数据的访问权限,保护了个人隐私。 另外,鸿蒙操作系统还支持开发者生态系统的建设,提供了一套丰富的开发工具和开发文档。这将吸引更多的开发者参与到鸿蒙生态中来,丰富应用程序的种类和质量。 总的来说,我认为鸿蒙操作系统在技术和用户体验方面都有很大的潜力。但与此同时,鸿蒙操作系统还处于起步阶段,尚需时间来完善和发展。我期待未来鸿蒙操作系统能给我们带来更好的使用体验和更广泛的应用领域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值