鸿蒙 自定义弹窗对CustomDialogController二次封装

前言:

鸿蒙官方提供了自定义customdialog,调用代码很臃肿,必须在当前页面创建customDialogController,否则无法正常弹窗dialog

解决方案:目前就定义了两种类型的dialog

具体代码如下:

1. 用于代理dialog的打开和关闭

export interface MyCustomDialogController {
  open: () => void
  close: () => void
}

2. 作为全局弹窗组件封装 内容完全由外部dialogContent定义

@CustomDialog
export default struct MyCustomDialog {
  controller: CustomDialogController
  @BuilderParam dialogContent: () => void

  build() {
    this.dialogContent()
  }
}

3.1. 具体实现,这里是ConfirmPop(对话框弹窗)

import MyCustomDialog from './core/MyCustomDialog';
import { MyCustomDialogController } from './core/MyCustomDialogController';
/**
 * @author: hwk
 * @description: 确认取消对话框弹窗
 * @date: 2024/3/7 10:33
 */
@Component
export default struct ConfirmPop {
  controller: MyCustomDialogController = null;
  alignment: DialogAlignment = DialogAlignment.Center; //弹窗位置
  offsetX: number = 0; //上下 偏移量 负数则往上
  offsetY: number = 0; //上下 偏移量 负数则往上
  autoCancel: boolean = false; //点击遮罩层是否关闭弹窗
  //api9不支持 maskColor: ResourceColor = "rgba(0,0,0,0.1)";
  customStyle: true;
  title: Resource;
  content: Resource;
  leftText: Resource = $r('app.string.quxiao');
  rightText: Resource = $r('app.string.queding');
  isHideRight: boolean = false; //是否隐藏右边按钮
  leftClick: () => void
  rightClick: () => void

  //下面两个是私有的
  @State leftDown: boolean = false; //左边按钮是否按下
  @State rightDown: boolean = false; //右边按钮是否按下


  build() {
  }

  @Builder buildContent() {
    Column() {
      Text(this.title)
        .fontSize(15)
        .fontColor($r('app.color.black3'))
        .maxLines(1)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
      Text(this.content)
        .fontSize(13)
        .fontColor($r('app.color.black6'))
        .maxLines(3)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .margin({ top: 13, bottom: 30 })
      Row() {
        Text(this.leftText)
          .height('100%')
          .width(86)
          .textAlign(TextAlign.Center)
          .fontSize(13)
          .backgroundColor(this.leftDown ? $r('app.color.theme') : $r('app.color.white'))
          .fontColor(this.leftDown ? $r('app.color.white') : $r('app.color.theme'))
          .border({ width: 1, color: $r('app.color.theme'), radius: 5, style: BorderStyle.Solid })
          .onTouch((event: TouchEvent) => {
            this.leftDown = (event.type != TouchType.Up);
          })
          .onClick(() => {
            this.controller.close()
            if (this.leftClick)
              this.leftClick()
          })

        Blank()
          .visibility(this.isHideRight ? Visibility.None : Visibility.Visible)
          .width(20)
          .height('100%')

        Text(this.rightText)
          .visibility(this.isHideRight ? Visibility.None : Visibility.Visible)
          .height('100%')
          .width(86)
          .textAlign(TextAlign.Center)
          .fontSize(13)
          .backgroundColor(this.rightDown ? $r('app.color.theme') : $r('app.color.white'))
          .fontColor(this.rightDown ? $r('app.color.white') : $r('app.color.theme'))
          .border({ width: 1, color: $r('app.color.theme'), radius: 5, style: BorderStyle.Solid })
          .onTouch((event: TouchEvent) => {
            this.rightDown = (event.type != TouchType.Up);
          })
          .onClick(() => {
            this.controller.close()
            if (this.rightClick)
              this.rightClick()
          })
      }
      .width('100%')
      .height(34)
      .padding({ left: 12, right: 12 })
      .justifyContent(FlexAlign.Center)
    }
    .width(250)
    .backgroundColor($r('app.color.white'))
    .borderRadius(5)
    .padding({ left: 17, right: 17, top: 12, bottom: 22 })
  }

  aboutToAppear() {
    //修正,这里要在这里初始化,否则 this.clickMaskClose 不能响应外部变更
    let dialogController = new CustomDialogController({
      builder: MyCustomDialog({
        dialogContent: () => {
          this.buildContent();
        }
      }),
      alignment: this.alignment,
      offset: { dx: 0, dy: this.offsetY },
      // maskColor: this.maskColor,
      autoCancel: this.autoCancel,
      //完全依靠外部样式控制,否则会有宽度限制和默认圆角, 这里需要的就是要自己控制样式
      customStyle: true
    });
    if (this.controller) {
      this.controller.open = () => {
        dialogController.open();
      }
      this.controller.close = () => {
        dialogController.close();
      }
    }
  }
}

3.2. 具体实现,这里是LoadingPop(加载中弹窗)

import MyCustomDialog from './core/MyCustomDialog';
import { MyCustomDialogController } from './core/MyCustomDialogController';
/**
 * @author: hwk
 * @description: 加载动画loading
 * @date: 2024/3/7 14:12
 */
@Component
export default struct LoadingPop {
  controller: MyCustomDialogController = null;
  alignment: DialogAlignment = DialogAlignment.Center; //弹窗位置
  offsetX: number = 0; //上下 偏移量 负数则往上
  offsetY: number = 0; //上下 偏移量 负数则往上
  autoCancel: boolean = false; //点击遮罩层是否关闭弹窗
  //api9不支持 maskColor: ResourceColor = "rgba(0,0,0,0.1)";
  customStyle: true;
  @State angle: number = 0

  build() {
  }

  @Builder buildContent() {
    Column() {
      ImageAnimator()
      Image($r('app.media.loading'))
        .width(50)
        .margin({ top: 16 })
        .rotate({ angle: this.angle })
        .animation({
          duration: 1500,
          curve: Curve.Linear,
          iterations: -1, // 设置-1表示动画无限循环
          playMode: PlayMode.Normal
        })
      Text('加载中...')
        .margin({ top: 16 })
        .fontColor($r('app.color.white'))
        .fontSize(12)
    }
    .width(111)
    .height(111)
    .borderRadius(5)
    .backgroundColor($r('app.color.transparent50'))
  }

  aboutToAppear() {

    //修正,这里要在这里初始化,否则 this.clickMaskClose 不能响应外部变更
    let dialogController = new CustomDialogController({
      builder: MyCustomDialog({
        dialogContent: () => {
          this.buildContent();
        }
      }),
      alignment: this.alignment,
      offset: { dx: 0, dy: this.offsetY },
      autoCancel: this.autoCancel,
      //完全依靠外部样式控制,否则会有宽度限制和默认圆角, 这里需要的就是要自己控制样式
      customStyle: true
    });
    if (this.controller) {
      this.controller.open = () => {
        dialogController.open();

        this.timeoutId = setTimeout(() => {
          this.angle = 360;
        }, 10)
      }
      this.controller.close = () => {
        clearTimeout(this.timeoutId);
        dialogController.close();
      }
    }
  }

  timeoutId: number;
}

4. 调用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/436852.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从安卓转战月薪6万的鸿蒙原来这么简单

近年来,各家大厂正在积极布局鸿蒙客户端开发,鸿蒙操作系统备受瞩目,不少安卓开发者纷纷转战鸿蒙,并取得了可观的经济回报。本文将为大家揭示,从安卓转战鸿蒙并获得月薪6万的简单之道,希望能给正在考虑转型的…

亿发解析:互联网浪潮席卷,新零售崛起成为未来十年无可忽视之势

随着人们消费能力和水平的提高,消费者对产品质量的关注已不再仅限于产品本身,而更加强调产品质量与消费服务体验的双重重要性。随着互联网、移动支付、快递物流等技术的发展,这些技术催生了零售领域的新模式、新经济和新业态,为新…

四信5G FWA家族再添猛将,让你一眼沦陷的5G CPE来了!

随着全球5G基础设施建设的日益完善,千行百业迎来巨大变革,越来越多的场景因为5G网络实现跨越式升级,人们生活早已离不开超高速的互联网连接。 5G FWA作为弥合光纤欠发达地区数字鸿沟挑战的“杀手级应用”,摆脱对传统有线网络基础设…

图形报表ECharts

1、 ECharts简介 ECharts缩写来自Enterprise Charts,商业级数据图表,是百度的一个开源的使用 JavaScript实现的数据可视化工具,可以流畅的运行在 PC 和移动设备上,兼容当前绝大 部分浏览器(IE8/9/10/11,Ch…

ubuntu下使用MATLAB过程中的若干问题

ubuntu版本:Ubuntu 20.04 内核:Linux 5.15.0-97-generic MATALB版本:MATLAB R2022b 问题1:运行脚本时闪退 报错信息: Inconsistency detected by ld.so: ../elf/dl-tls.c: 517: _dl_allocate_tls_init: Assertion l…

vue-cli项目因为webpack版本不兼容运行后报错

vue-cli项目运行后报错: Error: Rule can only have one resource source (provided resource and test include exclude) in {"exclude": [null],"use": [{"loader": "G:\\CustomerDay\\customerday\\node_modules\\cache-l…

制片管理工具:提高制片效率的必备工具

一、什么是制片管理工具 制片管理工具是一种为制片人提供支持和协助的软件或工具,并提供一种集中管理制作进度、任务分配、成本预算、资源管理和进度跟踪的方式。它可以帮助制片人在项目的开发、制作和发布方面更有效地进行规划和监督,确保整个流程能够…

redis-集群 原生部署和工具自动部署

什么redis集群? redis集群是一个提供在多个redis节点之间共享数据的程序集。它并不像redis主从复制模式那样仅提供一个master节点来提供写服务,而是会提供多个master节点来提供写服务,每个master节点中存储的数据都不一样,这些数据…

buildadmim生成代码时让菜单有层级

当我们使用buildadmin生成代码的时候,在菜单的部分, 有时希望它生的是一个带有层级的菜单,有时候则想生成一个没有层级的菜单 like this 经过本人测试 如果我们要生成没有层级的菜单 我们可以在高级设置中的 相对位置处更改,同时…

O2O:Adaptive policy learning for offline-to-online reinforcement learning

AAAI2023 paper Introduction 传统Online RL需要智能体与环境进行海量交互,而Offline RL容易受限于数据集质量。因此本文提出一种O2O的自适应策略学习框架APL。APL在离线阶段悲观更新策略而在现阶段乐观更新。进一步,基于框架分别提出value-based 以及…

蓝牙APP开发实现汽车遥控钥匙解锁汽车智能时代

在现代社会,随着科技的不断发展,汽车已经不再是简单的交通工具,而是与智能科技紧密相连的载体。其中,通过开发APP蓝牙程序实现汽车遥控钥匙成为了一种趋势,为车主带来了便捷与安全的体验。虎克技术公司作为行业领先者&…

Redis6 搭建主从集群架构

文章目录 搭建Redis主从集群架构1.集群结构2.准备实例和配置3.启动4.开启主从关系5.测试 搭建Redis主从集群架构 安装部署单机版Redis6可参考: 安装部署单机版Redis6 1.集群结构 我们搭建的主从集群结构如图: 我们计划是在一台虚拟机里去部署三个R…

区块链媒体套餐:精益求精链游媒体宣发推广7个关键细节分享-华媒舍

在如今竞争激烈的游戏行业,一款优秀的游戏缺乏有效的宣发推广,很难脱颖而出。而随着区块链技术的兴起,链游媒体的宣发推广成为游戏开发者和运营商的重要选择之一。本文将为大家介绍精益求精的链游媒体宣发推广的七个关键细节。 1. 定位目标受…

初学C++

注释 变量 作用:给一段指定的内存空间起名,方便操作这段内容 数据类型 变量名 变量初始值; 常量 用于记录程序中不可更改的数据 宏常量: #define 宏常量 常量值 const修饰的变量: const 数据类型 常量名 常量值; 关键字 …

从0到1入门C++编程——10 stack容器、queue容器、list容器、set容器、map容器

文章目录 一、stack容器二、queue容器三、list容器1、构造函数2、赋值和交换3、大小及判空4、插入和删除5、数据存取6、反转和排序7、排序案例 四、set/multiset容器1、构造和赋值2、大小和交换3、插入和删除4、查找和统计5、set和multiset的区别6、pair对组的创建7、排序及规则…

文献速递:深度学习疾病预后--临床级计算病理学使用基于整张切片图像的弱监督深度学习

Title 题目 Clinical-grade computational pathology using weakly supervised deep learning on whole slide images 临床级计算病理学使用基于整张切片图像的弱监督深度学习 01 文献速递介绍 The development of decision support systems for pathology and their deplo…

下载无水印抖音视频

在抖音看到某些视频想下载,却出现无法保存在本地【显示"作品暂时无法保存,链接已复制"】。或者下载的视频有水印。 而某些微信小程序下载可能需要付费或者有水印。其实我们可以直接使用电脑浏览器直接下载。 举个例子: 这是来自王道官方账号的一条视频链…

融合软硬件串流多媒体技术的远程控制方案

远程技术已经发展得有相当水平了,在远程办公,云游戏,云渲染等领域有相当多的应用场景,以向日葵,todesk rustdesk等优秀产品攻城略地,估值越来越高。占据了通用应用的方方面面。 但是细分市场,还…

【Simulink系列】——控制系统仿真基础

声明:本系列博客参考有关专业书籍,截图均为自己实操,仅供交流学习! 一、控制系统基本概念 这里就不再介绍类似于开环系统、闭环系统等基本概念了! 1、数学模型 控制系统的数学模型是指动态数学模型,大致…

开源文生图大模型Playground v2.5发布:超越SD、DALL·E 3和 Midjourney

前言 在AI技术迅速发展的今天,文生图模型成为了艺术创作、设计创新等领域的重要工具。Playground v2.5的发布,不仅在技术上取得了突破,更在开源文化的推广与实践上迈出了重要一步。 Huggingface模型下载:https://huggingface.co/…