【HarmonyOS Next】鴻蒙中自定義彈框OpenCustomDialog、CustomDialog與DialogHub的區別詳解

【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"}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72617.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72617.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72617.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C++】stack和queue的使用及模擬實現(含deque的簡單介紹)

文章目錄 前言一、deque的簡單介紹1.引入deque的初衷2.deque的結構3.為什么選擇deque作為stack和queue的底層默認容器 二、stack1.stack的介紹2.stack的使用3.stack的模擬實現 三、queue1.queue的介紹2.queue的使用3.queue的模擬實現 前言 一、deque的簡單介紹&#xff08;引入…

Leetcode 刷題筆記1 圖論part01

圖論的基礎知識&#xff1a; 圖的種類&#xff1a; 有向圖&#xff08;邊有方向&#xff09; 、 無向圖&#xff08;邊無方向&#xff09;、加權有向圖&#xff08;邊有方向和權值&#xff09; 度&#xff1a; 無向圖中幾條邊連接該節點&#xff0c;該節點就有幾度&#xff1…

《基于Workspace.java的Launcher3改造:HotSeat區域動態阻斷文件夾生成機制》

1. 需求背景與技術挑戰 在Android 13系統Launcher3定制化開發中&#xff0c;需實現禁止HotSeat區域創建文件夾的功能。原始邏輯中&#xff0c;當用戶拖拽應用圖標至HotSeat區域相鄰圖標時&#xff0c;會觸發FolderIcon的實例化。本文將深入分析Launcher3的文件夾創建機制&…

重生之我在學Vue--第14天 Vue 3 國際化(i18n)實戰指南

重生之我在學Vue–第14天 Vue 3 國際化(i18n)實戰指南 文章目錄 重生之我在學Vue--第14天 Vue 3 國際化(i18n)實戰指南前言一、Vue I18n 核心配置1.1 基礎環境搭建1.2 初始化配置1.3 全局掛載 二、多語言實現方案2.1 基礎使用2.2 動態切換語言2.3 高級功能實現復數處理日期/貨幣…

開源PACS(dcm4che-arc-light)部署教程,源碼方式

目錄 文件清單下載地址安裝概述OpenLDAP、Apache Directory StudioWildflydcm4che 安裝部署MySQL源碼編譯dcm4cheedcm4chee-arc-light OpenLDAP安裝ApacheDirectoryStudio安裝配置WildFly服務器 部署完成 文件清單 下載地址 Apache directory studio - linkOpenLDAP - linkdcm…

java使用(Preference、Properties、XML、JSON)實現處理(讀寫)配置信息或者用戶首選項的方式的代碼示例和表格對比

在Java應用程序中&#xff0c;處理應用首選項&#xff08;preferences&#xff09;有多種方法&#xff0c;包括使用java.util.prefs.Preferences類、屬性文件&#xff08;如.properties文件&#xff09;、XML文件和JSON文件。下面是每種方法的詳細說明和代碼示例&#xff0c;最…

工作記錄 2017-02-04

工作記錄 2017-02-04 序號 工作 相關人員 1 修改郵件上的問題。 更新RD服務器。 郝 更新的問題 1、DataExport的設置中去掉了ListPayors&#xff0c;見DataExport\bin\dataexport.xml 2、“IPA/Group Name” 改為 “Insurance Name”。 3、修改了Payment Posted的E…

dataframe數據形式操作中的diff和shift函數區別與對比

問題分析 從錯誤日志中可以看到&#xff0c;代碼在 report_services.py 的 gnss_monthly_report 函數中出現了 ValueError&#xff0c;具體錯誤信息是&#xff1a; ValueError: either both or neither of x and y should be given這個錯誤發生在以下代碼行&#xff1a; rep…

C語言動態內存管理(下)

歡迎拜訪&#xff1a;霧里看山-CSDN博客 本篇主題&#xff1a;C語言動態內存管理(下) 發布時間&#xff1a;2025.3.18 隸屬專欄&#xff1a;C語言 目錄 動態內存常見錯誤內存泄漏&#xff08;Memory Leak&#xff09;典型場景后果解決方案 懸掛指針&#xff08;Dangling Pointe…

Vue:Vue2和Vue3創建項目的幾種常用方式以及區別

前言 Vue.js 和 Element UI 都是用 JavaScript 編寫的。 1、Vue.js 是一個漸進式 JavaScript 框架。2、Element UI 是基于 Vue.js 的組件庫。3、JavaScript 是這兩個項目的主要編程語言。 而Element Plus是基于TypeScript開發的。 一、Vue2 1、基于vuecli工具創建 vue2 …

機器人曲面跟蹤Surface-Tracking

定義 機器人曲面跟蹤&#xff08;Surface-Tracking&#xff09;是指機器人通過實時感知工件曲面的三維形貌&#xff0c;動態調整運動軌跡和位姿&#xff0c;以精確跟隨曲面進行加工&#xff08;如打磨、拋光、噴涂等&#xff09;的技術。 力 - 位姿協同控制 力控模式&#xff…

網絡安全運維應急響應與溯源分析實戰案例

在日常運維過程中&#xff0c;網絡安全事件時有發生&#xff0c;快速響應和精準溯源是保障業務穩定運行的關鍵。本文將通過一個實際案例&#xff0c;詳細解析從發現問題到溯源定位&#xff0c;再到最終解決的完整流程。 目錄 一、事件背景 二、事件發現 1. 監控告警觸發 2…

【AVRCP】藍牙協議棧深度解析:AVCTP互操作性核心機制與實現細節

目錄 一、事務標簽&#xff08;Transaction Label&#xff09;機制 1.1 事務標簽核心規則 1.2 事務標簽作用域與并發性 1.3 實現建議與陷阱規避 1.4 協議設計思考 1.5 調試與驗證 二、消息分片&#xff08;Fragmentation&#xff09;機制 2.1 分片觸發條件 2.2 分片支…

harmonyOS NEXT開發與前端開發深度對比分析

文章目錄 1. 技術體系概覽1.1 技術棧對比1.2 生態對比 2. 開發范式比較2.1 鴻蒙開發范式2.2 前端開發范式 3. 框架特性對比3.1 鴻蒙 Next 框架特性3.2 前端框架特性 4. 性能優化對比4.1 鴻蒙性能優化4.2 前端性能優化 5. 開發工具對比5.1 鴻蒙開發工具5.2 前端開發工具 6. 學習…

OpenWebUI:一站式 AI 應用構建平臺體驗

&#x1f680; 大家好&#xff0c;今天給大家分享一個超棒的 AI 應用構建工具——OpenWebUI&#xff01;體驗下來&#xff0c;只能說絲滑&#xff01;必須強烈推薦&#xff01; &#x1f525; 聽說過阿里巴巴的 Qwen 嗎&#xff1f;他們最新的 Qwen Chat 網站就是用 OpenWebUI…

多線程—進程與線程

1 進程 1.1 進程概念 進程&#xff1a;操作系統提供的一種抽象&#xff0c;當程序在運行時&#xff0c;好像計算機的所有硬件資源都在為其服務。換言之&#xff0c;進程就是程序的一次運行過程。進程是操作系統分配資源的基本單位。 注意&#xff1a;區分進程和程序&#xff0…

[原創](Modern C++)現代C++的關鍵性概念: 靈活多變的綁定: std::bind

[作者] 常用網名: 豬頭三 出生日期: 1981.XX.XX 企鵝交流: 643439947 個人網站: 80x86匯編小站 編程生涯: 2001年~至今[共24年] 職業生涯: 22年 開發語言: C/C、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 開發工具: Visual Studio、Delphi、XCode、C …

ssm框架之mybatis框架動態SQL

1 mybatis動態sql mybatis可以通過各種各樣的標簽在sql映射文件中實現如下功能 1、語句的動態拼接 2、前后綴格式處理 3、復雜參數處理 常用標簽如下&#xff1a; 1.1 if標簽 如下示例&#xff0c;當有一個入參為null或者空的時候的時候&#xff0c;不參與計算&#xff0c;…

Spring Boot 事務詳解

Spring Boot 事務詳解 引言 在現代應用程序中&#xff0c;事務管理是確保數據一致性和完整性的重要機制。Spring Boot 提供了強大的事務管理功能&#xff0c;使得開發者可以輕松地定義和管理事務。本文將詳細介紹 Spring Boot 中的事務管理&#xff0c;包括事務傳播行為、事務…

poetry使用

1.初始化 package name 填入口文件名 poetry init2.在本目錄下虛擬 poetry config virtualenvs.in-project true 3.自動生成依賴文件和vent虛擬環境&#xff0c;管理本項目下載包 poetry add flask pandas numpy 4 4.下載依賴 poetry install 5.查看都安裝了什么包 poe…