您的位置:首页 > 文旅 > 旅游 > 100个免费b站_陕西建设网查证件查询_北京百度网站排名优化_上海单个关键词优化

100个免费b站_陕西建设网查证件查询_北京百度网站排名优化_上海单个关键词优化

2025/3/19 18:39:57 来源:https://blog.csdn.net/u010949451/article/details/146353991  浏览:    关键词:100个免费b站_陕西建设网查证件查询_北京百度网站排名优化_上海单个关键词优化
100个免费b站_陕西建设网查证件查询_北京百度网站排名优化_上海单个关键词优化

【HarmonyOS Next】鸿蒙中自定义弹框OpenCustomDialog、CustomDialog与DialogHub的区别详解

一、三者的区别与关系

1. 官方迭代过程为
CustomDialog = 》 OpenCustomDialog = 》 DialogHub

迭代过程表明,弹框的调用越来越便捷,与UI解耦,最终达到在纯逻辑中使用自定义弹出,弹框内容更新和生命周期可控,写法简洁。

2.CustomDialog的用法:
首先需要创建@CustomDialog装饰的自定义弹框布局,CustomDialogController来实现弹窗弹出和关闭。


struct CustomDialogUI {// CustomDialog可直接获取到dialogControllerdialogController: CustomDialogController;// 定义事件回调给外部使用onClose?: () => void;build() {Column() {Text('我是内容').fontSize(20)Button('Close').onClick(() => {// 点击关闭弹框this.dialogController.close();if (this.onClose) {this.onClose()}}).backgroundColor(Color.White).fontColor(Color.Black)}.height(60).justifyContent(FlexAlign.Center)}
}

struct CustomDialogPage {// CustomDialog - CustomDialogController需在@Component内定义初始化。dialogController: CustomDialogController | null = new CustomDialogController({builder: CustomDialogUI({onClose: ()=> {console.info('Callback when the onClose button is clicked')},}),})build() {Column() {Button('click me').onClick(() => {this.dialogController.open()})}.width('100%').margin({ top: 5 })}
}

综上所述,CustomDialog 因为CustomDialogController强耦合于UI,需要在UI界面或者自定义View中使用CustomDialogController控制弹框显示隐藏。无法在纯逻辑类中处理弹框时机的显示。(这种情况下只能想办法发送通知给UI,UI再处理回调显示,处理起来麻烦。)致命的问题是,弹框内的UI无法动态刷新。需要重新创建渲染。

3.OpenCustomDialog 的用法:
对标CustomDialog 的CustomDialogController。官方通过将弹框对象实例,放到上下文中,实现在纯逻辑类中也可以调用弹框的显示和隐藏。

将@CustomDialog弹框布局内容,放到ComponentContent节点对象中,实现弹框UI的解耦。


function ComponentContentBuildText() {Column() {Text("测试数据").fontSize(50).fontWeight(FontWeight.Bold).margin({ bottom: 36 })}.backgroundColor('#FFF0F0F0')
}// OpenCustomDialog - ComponentContent // 建议整体抽个单例private contentNode: ComponentContent<Object> = new ComponentContent(this.getUIContext(), wrapBuilder(ComponentContentBuildText));this.getUIContext().getPromptAction().openCustomDialog(this.contentNode).then(() => {console.info('UpdateCustomDialog complete.')}).catch((error: BusinessError) => {let message = (error as BusinessError).message;let code = (error as BusinessError).code;console.error(`onClickOpenCustomDialog args error code is ${code}, message is ${message}`);})

DialogHub的用法:
参考:【HarmonyOS Next】鸿蒙应用实现弹框DialogHub详解

二、自定义View与UI解耦的解决方案:

目前共有三种方式,使用浮层(DialogHub底层原理),使用OpenCustomDialog,使用subWindow。

1.浮层
在这里插入图片描述
DialogHub底层原理。在页面Page与弹框层之间,ArkUI框架有一个浮层。该层通过节点管控(增加,删除)的方式,可以插入自定义UI。

ComponentContent可以理解为一个节点内容对象,在其中进行自定义UI的界面编写,打包为一个ComponentContent节点,添加到浮层上,ArkUI框架就会加载显示。



function builderOverlay() {Column() {
}.focusable(false).width('100%').height('100%').hitTestBehavior(HitTestMode.Transparent)
}private overlayNode: OverlayManager = this.uiContext.getOverlayManager()let componentContent = new ComponentContent(this.uiContext, wrapBuilder<>(builderOverlay))this.overlayNode.addComponentContent(componentContent, 0)this.overlayContent.push(componentContent)

2.OpenCustomDialog
参考:【HarmonyOS Next】鸿蒙应用弹框和提示气泡详解(一)

3.subWindow
因为三方应用不能使用FloatWindow,没有悬浮窗。只能通过子窗口SubWindow实现独立的自定义View层级。

import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

struct SubWinPage {private TAG: string = "SubWinPage";private sub_windowClass: window.Window | null = null;aboutToAppear() {this.showSubWindow()setTimeout(()=>{try {this.destroySubWindow();// window.getLastWindow(getContext()).then((win)=>{//   console.error(this.TAG, 'win:' + JSON.stringify(win));//   let height = win.getWindowDecorHeight();//   console.error(this.TAG, 'height:' + height);// })let windowStage_:  window.WindowStage = globalThis.mWindowStage;let win = windowStage_.getMainWindowSync();let height = win.getWindowDecorHeight();}catch (e){console.error(this.TAG, 'e:' + JSON.stringify(e));}},1000)}private showSubWindow() {console.log(this.TAG, 'showSubWindow start');let windowStage_:  window.WindowStage = globalThis.mWindowStage;// 1.创建应用子窗口。if (windowStage_ == null) {console.error(this.TAG, 'Failed to create the subwindow. Cause: windowStage_ is null');}else {windowStage_.createSubWindow("mySubWindow", (err: BusinessError, data) => {let errCode: number = err.code;if (errCode) {console.error(this.TAG, 'Failed to create the subwindow. Cause: ' + JSON.stringify(err));return;}this.sub_windowClass = data;console.info(this.TAG, 'Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));// 2.子窗口创建成功后,设置子窗口的位置、大小及相关属性等。this.sub_windowClass.moveWindowTo(300, 300, (err: BusinessError) => {let errCode: number = err.code;if (errCode) {console.error(this.TAG, 'Failed to move the window. Cause:' + JSON.stringify(err));return;}console.info(this.TAG, 'Succeeded in moving the window.');});this.sub_windowClass.resize(500, 500, (err: BusinessError) => {let errCode: number = err.code;if (errCode) {console.error(this.TAG, 'Failed to change the window size. Cause:' + JSON.stringify(err));return;}console.info(this.TAG, 'Succeeded in changing the window size.');});// 3.为子窗口加载对应的目标页面。this.sub_windowClass.setUIContent("pages/SubWinLoadPage", (err: BusinessError) => {let errCode: number = err.code;if (errCode) {console.error(this.TAG, 'Failed to load the content. Cause:' + JSON.stringify(err));return;}console.info(this.TAG, 'Succeeded in loading the content.');// 3.显示子窗口。(this.sub_windowClass as window.Window).showWindow((err: BusinessError) => {let errCode: number = err.code;if (errCode) {console.error(this.TAG, 'Failed to show the window. Cause: ' + JSON.stringify(err));return;}console.info(this.TAG, 'Succeeded in showing the window.');});});})}console.log(this.TAG, 'showSubWindow end');}destroySubWindow() {// 4.销毁子窗口。当不再需要子窗口时,可根据具体实现逻辑,使用destroy对其进行销毁。(this.sub_windowClass as window.Window).destroyWindow((err: BusinessError) => {let errCode: number = err.code;if (errCode) {console.error(this.TAG, 'Failed to destroy the window. Cause: ' + JSON.stringify(err));return;}console.info(this.TAG, 'Succeeded in destroying the window.');});}build() {Column() {Text("点击创建子窗口").id('SubWinPageHelloWorld').fontSize(50).fontWeight(FontWeight.Bold).onClick(()=>{this.showSubWindow();})Text("点击销毁子窗口").id('SubWinPageHelloWorld').fontSize(50).fontWeight(FontWeight.Bold).onClick(()=>{this.destroySubWindow();})}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}

三、多弹框源码示例:

import {DialogHub
} from "@hadss/dialoghub"
import { ComponentContent } from "@kit.ArkUI";
import { BusinessError } from "@kit.BasicServicesKit";
struct CustomDialogUI {// CustomDialog可直接获取到dialogControllerdialogController: CustomDialogController;// 定义事件回调给外部使用onClose?: () => void;build() {Column() {Text('我是内容').fontSize(20)Button('Close').onClick(() => {// 点击关闭弹框this.dialogController.close();if (this.onClose) {this.onClose()}}).backgroundColor(Color.White).fontColor(Color.Black)}.height(60).justifyContent(FlexAlign.Center)}
}
function ComponentContentBuildText() {Column() {Text("测试数据").fontSize(50).fontWeight(FontWeight.Bold).margin({ bottom: 36 })}.backgroundColor('#FFF0F0F0')
}/*** 弹框测试页*/


struct DialogTestPage {// CustomDialog - CustomDialogController需在@Component内定义初始化。dialogController: CustomDialogController | null = new CustomDialogController({builder: CustomDialogUI({onClose: ()=> {console.info('Callback when the onClose button is clicked')},}),})// OpenCustomDialog - ComponentContent // 建议整体抽个单例private contentNode: ComponentContent<Object> = new ComponentContent(this.getUIContext(), wrapBuilder(ComponentContentBuildText));/*** 统一样式封装*/ ButtonStyle(){.width(px2vp(350)).height(px2vp(200)).margin({ top: px2vp(66) })}/*** 点击显示CustomDialog弹框 【官方不推荐】*/onClickCustomDialog = ()=>{this.dialogController?.open()}/*** 点击显示OpenCustomDialog*/onClickOpenCustomDialog = ()=>{this.getUIContext().getPromptAction().openCustomDialog(this.contentNode).then(() => {console.info('UpdateCustomDialog complete.')}).catch((error: BusinessError) => {let message = (error as BusinessError).message;let code = (error as BusinessError).code;console.error(`onClickOpenCustomDialog args error code is ${code}, message is ${message}`);})}/*** 点击显示DialogHub弹框*/onClickDialogHub = ()=>{DialogHub.getToast().setTextContent("测试数据").setDuration(2000).build().show();}aboutToDisappear() {// 在自定义组件即将析构销毁时将dialogController置空this.dialogController = null; // 将dialogController置空}build() {Column(){Button("customDialog").ButtonStyle().onClick(this.onClickCustomDialog)Button("openCustomDialog").ButtonStyle().onClick(this.onClickOpenCustomDialog)Button("dialogHub").ButtonStyle().onClick(this.onClickDialogHub)}.size({width: "100%",height: "100%"})}
}
{"name": "entry","version": "1.0.0","description": "Please describe the basic information.","main": "","author": "","license": "","dependencies": {"@hadss/dialoghub": "^1.0.0-rc.1"}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com