当前位置: 首页 > article >正文

【HarmonyOS Next】鸿蒙应用实现弹框DialogHub详解

【HarmonyOS Next】鸿蒙应用实现弹框DialogHub详解

一、前言

鸿蒙中实现弹框目前官方提供openCustomDialog和CustomDialog两种模式。推荐前者,详情见下图和官网文档链接:
在这里插入图片描述
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-uicontext-custom-dialog-V14
UI强绑定的实现方式API已标注不推荐。推荐使用UI框架层预留挂靠节点的方式,即openCustomDialog。

这两者的差别详见【HarmonyOS Next】鸿蒙应用弹框和提示气泡详解(一)

除此之外开源三方库DialogHub可以更加快捷的使用弹窗:
在这里插入图片描述
https://gitee.com/hadss/dialoghub

DialogHub底层实现原理为,使用浮层OverlayManager➕半模态页面bindSheet来实现弹框。
可以达到我们在传统Android和IOS开发中,弹框与页面生命周期绑定的效果(页面隐藏,弹框隐藏。页面销毁,弹框销毁)

DialogHub接口属性详细信息如下:
https://gitee.com/hadss/dialoghub/blob/master/docs/Reference.md
在这里插入图片描述

二、DialogHub的使用

目前DialogHub还是RC版本,并非Final版本。请谨慎使用。

目前DialogHub可以实现的弹框效果如下:
在这里插入图片描述
使用起来很简单,通过三方库通过级联的方式,获取弹框实例对象,设置弹框的样式,布局,和弹框上的属性。甚至连弹框内容模板的设置和数据的更新也通过级联属性设置,这个思路不错。

// 导依赖包之后就可操作DialogHub对象
import {
  DialogHub
} from "@hadss/dialoghub"

在这里插入图片描述
如图所示,红框中提供了默认的三种样式的弹框。以Toast弹框举例:

  showToastTest(){
    DialogHub.getToast()
      .setContent(wrapBuilder(TextToastBuilder))
        // 自定义内容					
      .setConfig(CommonConstant.CUSTOM_SAMPLE_CONFIG)
        // 持续时间			
      .setDuration(CommonConstant.DURATION_3000)
      .build()
      .show();

  }

  // 布局的内容
  
  TextToastBuilder() {
    Stack() {
      Text("测试文本")
        .fontColor(Color.Black)
        .fontSize(52)
    }
    .padding({ left: 20, right: 20 })
    .height(100)
  }

自定义弹框:

        this.specifiedLocationDialog = this.specifiedLocationDialog ?? DialogHub.getCustomDialog()
                      .setOperableContent(wrapBuilder(SnackbarBuilder), (action: DialogAction) => {
                        let param = new SnackbarParams(() => {
                          action.dismiss()
                        }, this.pageInfos)
                        return param
                      })
                      // DocsDot
                      .setStyle({
                        radius: $r('app.float.custom_template_sample_radius'),
                        shadow: CommonConstant.CUSTOM_SAMPLE_STYLE_SHADOW
                      })
                      // DocsDot
                      .setConfig({
                        dialogBehavior: { isModal: false, passThroughGesture: true },
                        dialogPosition: {
                          alignment: DialogAlignment.Bottom,
                          offset: { dx: 0, dy: $r('app.float.specified_location_offset') }
                        }
                      })
                      .build();
                    this.specifiedLocationDialog.show();

更新弹框内容:

   let intervalID: number = -1;
                    let time: number = CommonConstant.TIMED_DIALOG_DURATION;
                    let params: TimeToastParams =
                      new TimeToastParams(CommonConstant.TIMED_DIALOG, time + CommonConstant.TIMED_CLOSED);
                    // DocsCode 5
                    this.intervalsDisappearsDialog = this.intervalsDisappearsDialog ?? DialogHub.getCustomDialog()
                      .setContent(wrapBuilder(TimeToastBuilder), params)
                      .setStyle({
                        radius: $r('app.float.popup_disappears_intervals_radius'),
                        shadow: CommonConstant.CUSTOM_SAMPLE_STYLE_SHADOW
                      })
                      .setAnimation({ dialogAnimation: AnimationType.UP_DOWN })
                      .setConfig({
                        dialogBehavior: { isModal: false, passThroughGesture: true },
                        dialogPosition: {
                          alignment: DialogAlignment.Top,
                          offset: { dy: $r('app.float.popup_disappears_intervals_offset'), dx: 0 }
                        }
                      })
                      .build();

                    this.intervalsDisappearsDialog.show();

                    intervalID = setInterval(() => {
                      time -= 1;
                      params.content = time + CommonConstant.TIMED_CLOSED;
                      this.intervalsDisappearsDialog?.updateContent(params)
                      if (time <= 0 && intervalID) {
                        this.intervalsDisappearsDialog?.dismiss();
                        clearInterval(intervalID);
                      }
                    }, CommonConstant.DURATION_1000);

三、源码示例

首先配置依赖:

{
  "modelVersion": "5.0.0",
  "description": "Please describe the basic information.",
  "dependencies": {
    "@hadss/dialoghub": "^1.0.0-rc.1"
  },
  "devDependencies": {
    "@ohos/hypium": "1.0.19",
    "@ohos/hamock": "1.0.0"
  },
  "dynamicDependencies": {}
}

之后导入包,进行调用:

import { DialogHub } from '@hadss/dialoghub';
import { getContext } from '@ohos.app.ability';
import CommonConstant from '../utils/CommonConstant';

// 假设的 TextToastParams 类型
interface TextToastParams {
    title?: string;
}

// TextToastBuilder 构建器函数

export function TextToastBuilder(param: TextToastParams) {
    Stack() {
        Text(param?.title ?? CommonConstant.PURE_TEXT)
           .fontColor($r('app.color.item_text_color'))
           .fontSize($r('app.float.font_size_regular'))
    }
   .padding({ left: $r('app.float.text_toast_padding'), right: $r('app.float.text_toast_padding') })
   .height($r('app.float.text_toast_height'))
}

// 假设的组件扩展,用于按钮样式
(Button)
function superFancyButton() {
    return this
       .width(CommonConstant.FULL_LENGTH)
       .height($r('app.float.index_action_height'))
       .margin({ bottom: $r('app.float.index_action_margin') })
       .fontSize($r('app.float.font_size_medium'))
       .fontWeight(FontWeight.Medium)
       .backgroundColor($r('app.color.base_blue'));
}



struct DialogHubExample {
    // 获取 UI 上下文
    getUIContext() {
        return getContext();
    }

    aboutToAppear(): void {
        // 初始化 DialogHub
        DialogHub.init(this.getUIContext());
        // 开启日志
        DialogHub.openLog('DEBUG');

        // 创建自定义模板
        DialogHub.createCustomTemplate(CommonConstant.CUSTOM_TEMPLATE_SIMPLE)
           .setContent(wrapBuilder(TextToastBuilder))
           .setStyle({ backgroundColor: Color.White })
           .setConfig({ dialogBehavior: { passThroughGesture: true, isModal: false } })
           .register();
    }

    showCustomDialog() {
        // 显示自定义模板的弹框
        DialogHub.show({
            templateName: CommonConstant.CUSTOM_TEMPLATE_SIMPLE,
            data: {
                // 传递数据给弹框
                title: '这是自定义弹框的标题'
            }
        });
    }

    build() {
        Column({ space: 20 }) {
            Button('显示自定义弹框', { stateEffect: true, type: ButtonType.Capsule })
               .superFancyButton()
               .onClick(() => {
                    this.showCustomDialog();
                });
        }
       .width('100%')
       .height('100%')
       .padding({ top: 20, bottom: 20, left: 20, right: 20 });
    }
}
    

http://www.kler.cn/a/592754.html

相关文章:

  • 标准 Git Commit 模板格式指南
  • 【第14节】windows sdk编程:进程与线程介绍
  • Java-泛型总结
  • 如何使用PHP爬虫根据关键词获取Shopee商品列表?
  • 两个docker app调用
  • 2025年2月AGI技术月评|重构创作边界:从视频生成革命到多模态生态的全面爆发
  • 【华为OD-E卷 - 求符合条件元组个数 100分(python、java、c++、js、c)】
  • Django初窥门径-Django REST Framework 基础使用
  • 单片机—中断系统
  • L2TP实验 作业
  • 数据通信与计算机网络——网络模型
  • 10、基于osg引擎生成热力图高度图实现3D热力图可视化、3D热力图实时更新(带过渡效果)
  • skywalking微服务链路追踪
  • LLVM学习--外部项目
  • Mistral AI发布开源多模态模型Mistral Small 3.1:240亿参数实现超越GPT-4o Mini的性能
  • NVIDIA Isaac GR00T N1:世界首个开源通用人形机器人基础模型
  • 3D点云数据处理中的聚类算法总结
  • 15 数据结构及算法应用
  • 蓝桥杯真题——洛谷Day13 找规律(修建灌木)、字符串(乘法表)、队列(球票)
  • SqlServer Sql学习随笔