HarmonyOS/OpenHarmony 自定义弹窗页面级层级控制解决方案

关键词:CuntomDialog自定义弹窗SubWindow子窗口、页面级、弹窗层级控制鸿蒙、弹窗展示层级异常

问题存在API版本:API10 - API12(该问题已反馈,期望后续官方能增加页面级控制能力)

在正常的鸿蒙app开发过程中,时常会加载一些弹窗内容,比如隐私政策弹窗、新手引导弹窗、营销广告弹窗等。那么我们会选择使用 CuntomDialog 或创建 SubWindow 的形式去展示出我们的弹窗,但是目前鸿蒙的弹窗存在 2 个问题

①弹窗无法保持在目标页面的问题鸿蒙自定义弹窗或子窗口由于展示优先级高于其他组件,则会出现当弹窗正在展示时跳转进入下一个页面后,弹窗依旧展示在 app 最上层的异常情况,或当折叠屏设备分屏后展示出弹窗,合起折叠屏后,弹窗同样会展示在下一个页面上的异常情况。

②无法控制弹窗展示优先级的问题:如当前存在 2 个弹窗,先展示弹窗 B,后展示弹窗 A,同时要求弹窗 A 展示在弹窗 B 上层,当前的鸿蒙弹窗并不支持这样的操作,仅为谁后来谁在上的原则。

 解决前    解决后

那么我们应该如何解决这 2 种情况?想要解决该问题,那我们就不能再去使用这两种弹窗方式。要想弹窗仅展示在我们的目标页面中,那么我们就应该使用 Stack 层叠布局的形式去改造我们的页面整体结构,从页面左上角 0vp 处摆放一个宽高均为 0vp 的组件当作我们的弹窗展示容器,将所有的弹窗都统一管理在该组件中,用状态变量实现控制显隐弹窗的操作,明确目标那么开始。

本期文章完整demo以上传至Gitee:Harmony 自定义弹窗页面级控制解决方案

1. Stack 布局改造页面结构

将以往弹窗逻辑由图1 调整至图2 ,第 2 步开始将介绍 DialogView 自定义组件的用法。

图1(改造前)

图2(改造后)

2. DialogView 自定义组件的实现

经过第 1 步的改造后,我们已经在页面左上角提前占位了弹窗展示区域,在该 DialogView 自定义组件中,统一管理我们的弹窗组件,这样我们也就可以自行编排布局控制弹窗的展示层级与先后顺序了。

可以使用 Column 组件直接控制弹窗展示顺序(当2个及以上的弹窗同时展示时,其他组件会在屏幕外等待展示,上一个弹窗隐藏后,下一个弹窗展示)
或使用 Stack 组件直接控制弹窗展示层级(当2个及以上的弹窗同时展示时,各弹窗同时展示在页面上,可自行摆放弹窗的上下层级关系)

这里我们就按照两个弹窗都展示在屏幕内的业务,使用 Stack 布局。

3. DialogViewController 控制器的实现

在前2步中已经初步实现了弹窗的页面级与层级的控制,那么如何做到弹窗动态的展示或隐藏操作?

首先我们需要了解,鸿蒙应用开发过程中,要想改变 UI 展示效果,需要配合使用一系列的状态装饰器,使属性成为状态变量,当被状态装饰器装饰的属性发生变化后,在页面UI中使用到该属性的地方,都会触发UI更新,如最直观的就是 @State 装饰器。

就目前场景而言,弹窗与主页面之间已经出现跨组件的情况了,实际开发过程中业务场景会更为复杂,所以我们可以直接使用 class 类配合 @Observed 装饰器实现跨组件之间的数据通讯,只需在父组件创建出目标对象,传递至弹窗组件,并用 @ObjectLink 绑定接收即可,这样做的好处是,不管途中经过多少组件,弹窗组件调用该对象方法,也能改变途中使用到该对象方法的UI,并且能够更好的统一管理所有的弹窗状态(或直接使用单例形式导出,在目标弹窗组件直接使用 @State 装饰器接收该单例对象即可,无需在根页面 new 出控制器对象进行逐级传递)。

如下图所示,DialogViewController 仅为 2 个弹窗展示状态的属性,并进行私有,使用对外提供的各种方法获取或改变二者属性的值。

更多装饰器相关使用请参考官方文档,此处就不过多赘述:harmonyOS文档中心 - 状态管理

4. 弹窗内布局如何编排

我们从步骤 1 开始改造布局到步骤 2 的自定义弹窗组件实现,都并未看到对弹窗进行宽度高度的设置,那我们的弹窗应该如何铺满屏幕?以 PrivacyDialog 为例,我们只需要在需要展示的弹窗上设置对应的宽度及高度即可,当弹窗不展示,则在第 2 步中 DialogView 的宽高为 0,该方式可避免在没有弹窗时的情况下,弹窗组件影响主页面触摸点击事件的影响。

5. 完整demo

本期文章完整demo已提交至Gitee,可回顶部查看。

6. end

此处打个广告介绍下我开发的 markdown 预览解析三方库,@luvi/lv-markdown-in


http://www.niftyadmin.cn/n/5692274.html

相关文章

Elasticsearch学习笔记(六)使用集群令牌将新加点加入集群

随着业务的增长,陆续会有新的节点需要加入集群。当我们在集群中的某个节点上使用命令生成令牌时会出现报错信息。 # 生成令牌 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node出现报错信息: Unable to create enrollment…

国庆作业-5

C语言练习-1 C语言练习-2 C练习-1 C练习-2

第五节——转移表(让你不再害怕指针)

文章目录 制作简易计算器什么是转移表?switch函数实现函数指针数组实现 制作简易计算器 要求:制作一个简易计算器,可以进行* / - 等功能运算。 什么是转移表? 指的就是通过函数指针数组的方式通过数组去调用里面的函数&#x…

5QI(5G QoS Identifier)

5QI(5G QoS Identifier,5G 服务质量标识符)是在5G网络中用于定义特定数据流所需服务级别的指标。它用于优先处理流量,并根据流量的类型及其特定需求分配网络资源。5QI值从1到255,每个值对应一组QoS参数,这些…

教你快速成为洛谷红名大佬!2分钟学会,2个月成功!

大家好,我是 zhouxi2022HZO,洛谷账号:876268。今天教大家如何在洛谷上快速红名。 我们分两段,一段是为蓝名绿名定制的,一段是为橙名和不稳定的红名定制的。 如果你是蓝名绿名 首先,你需要有一定的 C \t…

5.8K Star,Microsoft 官方开源电商平台

Hi,骚年,我是大 G,公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目,一分钟 get 一个优秀的开源项目,挖掘开源的价值,欢迎关注。 随着微服务架构和容器化技术的逐渐普及,越来越多的开发者…

Docker系列-5种方案超详细讲解docker数据存储持久化(volume,bind mounts,NFS等)

文章目录 Docker的数据持久化是什么?1.数据卷(Data Volumes)使用Docker 创建数据卷创建数据卷创建一个容器,将数据卷挂载到容器中的 /data 目录。进入容器,查看数据卷内容停止并重新启动容器,数据卷中的数据…

运动传感器

运动传感器 当你走近一些自动开关门、自动开关灯泡或自动启动自动扶梯的地方时,你是否会产生这样的疑问:**"它是怎么做到的? **它是怎么做到的? 如果有,本教程不仅会回答,还会告诉你如何制作。 让我们…