HarmonyOS 鸿蒙Next:在公共的class里面弹出局部的弹窗,应该怎么做?

发布于 1周前 作者 itying888 来自 鸿蒙OS

HarmonyOS 鸿蒙Next:在公共的class里面弹出局部的弹窗,应该怎么做?
找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

关于HarmonyOS 鸿蒙Next:在公共的class里面弹出局部的弹窗,应该怎么做?的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。

6 回复
就是不依赖在唯一的一个页面,在全局可以调用的,局部弹窗,注意不是全屏弹窗,是局部的,其余部分可以交互的,应该怎么做

cke_129.png

原理参考:https://developer.huawei.com/consumer/cn/forum/topic/0202156174901893142?fid=0109140870620153026

示例代码

src/main/ets/common/MyPromptActionUtil.ets

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

// MyPromptInfo 类用于生成唯一的 dialogID export class MyPromptInfo { public dialogID: string

constructor() { this.dialogID = this.generateRandomString(10) }

// 生成指定长度的随机字符串 generateRandomString(length: number): string { const characters = ‘abcdefghijklmnopqrstuvwxyz0123456789’; let result = ‘’;

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; length; i++) {
  <span class="hljs-keyword">const</span> randomIndex = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * characters.length);
  result += characters.charAt(randomIndex);
}

<span class="hljs-keyword">return</span> result;

} }

// MyPromptActionUtil 类用于封装弹窗操作 export class MyPromptActionUtil<T extends MyPromptInfo> { static myDialogPromptActionUtil: MyPromptActionUtil<MyToastInfo> | undefined = undefined

public static showToast(message: string) { if (!MyPromptActionUtil.myDialogPromptActionUtil) { //当前页面没显示toast // getContext().eventHub.off(MyPromptActionUtil.myDialogPromptActionUtil?.dialogID) // MyPromptActionUtil.myDialogPromptActionUtil?.closeCustomDialog() //如果之前有的toast对话框,并且正在显示,则先关闭toast提示 window.getLastWindow(getContext()).then((windowClass) => { const uiContext = windowClass.getUIContext() MyPromptActionUtil.myDialogPromptActionUtil = new MyPromptActionUtil<MyToastInfo>(uiContext, wrapBuilder(myToastView), new MyToastInfo(message)) .setModal(false)//true:存在黑色半透明蒙层,false:没有蒙层 .setSwipeBackEnabled(false)//true:侧滑允许关闭弹窗 .setMaskTapToCloseEnabled(true)//true:点击半透明蒙层可关闭弹窗【注:如果setModal(false),那么就没有蒙层,所以点击对话框外也没有响应事件,也就是这里设置了也没效果,并且事件会穿透】 .setAlignment(DialogAlignment.Center) .onWillAppear(() => { console.info(‘在对话框的打开动画开始之前调用的回调函数’) getContext().eventHub.on(MyPromptActionUtil.myDialogPromptActionUtil?.dialogID, (data: string) => { //监听结果 if (data == ‘关闭弹窗’) { MyPromptActionUtil.myDialogPromptActionUtil?.closeCustomDialog() } }) }) .onWillDisappear(() => { console.info(‘在对话框的关闭动画开始之前调用的回调函数’) getContext().eventHub.off(MyPromptActionUtil.myDialogPromptActionUtil?.dialogID) MyPromptActionUtil.myDialogPromptActionUtil = undefined }) .showCustomDialog() }) }

}

private uiContext: UIContext; private promptAction: PromptAction; private contentNode: ComponentContent<T> | undefined; private wrapBuilder: WrappedBuilder<[T]>; private t: T; private isModal: boolean = true; private alignment: DialogAlignment = DialogAlignment.Center; private isSwipeBackEnabled: boolean = true; private isMaskTapToCloseEnabled: boolean = true; public dialogID: string

constructor(uiContext: UIContext, wrapBuilder: WrappedBuilder<[T]>, t: T) { this.uiContext = uiContext; this.promptAction = uiContext.getPromptAction(); this.wrapBuilder = wrapBuilder; this.t = t; this.dialogID = t.dialogID }

setSwipeBackEnabled(isSwipeBackEnabled: boolean) { this.isSwipeBackEnabled = isSwipeBackEnabled; return this; }

setMaskTapToCloseEnabled(isMaskTapToCloseEnabled: boolean) { this.isMaskTapToCloseEnabled = isMaskTapToCloseEnabled return this; }

setAlignment(alignment: DialogAlignment) { this.alignment = alignment; return this; }

setModal(isModal: boolean) { this.isModal = isModal; return this; }

onDidAppear(callback: () => void) { this.onDidAppearCallback = callback; return this; }

onDidDisappear(callback: () => void) { this.onDidDisappearCallback = callback; return this; }

onWillAppear(callback: () => void) { this.onWillAppearCallback = callback; return this; }

onWillDisappear(callback: () => void) { this.onWillDisappearCallback = callback; return this; }

private onDidAppearCallback?: () => void; private onDidDisappearCallback?: () => void; private onWillAppearCallback?: () => void; private onWillDisappearCallback?: () => void;

closeCustomDialog() { if (this.contentNode) { this.promptAction.closeCustomDialog(this.contentNode); } return this; }

// 显示自定义弹窗 showCustomDialog() { try { if (!this.contentNode) { this.contentNode = new ComponentContent(this.uiContext, this.wrapBuilder, this.t); } this.promptAction.openCustomDialog(this.contentNode, { // 打开自定义弹窗 alignment: this.alignment, isModal: this.isModal, showInSubWindow: false, maskRect: { x: 0, y: 0, width: ‘100%’, height: ‘100%’ }, onWillDismiss: (dismissDialogAction: DismissDialogAction) => { //弹窗响应 console.info(“reason” + JSON.stringify(dismissDialogAction.reason)) console.log(“dialog onWillDismiss”) if (dismissDialogAction.reason == 0 && this.isSwipeBackEnabled) { //手势返回时,关闭弹窗。 this.promptAction.closeCustomDialog(this.contentNode) } if (dismissDialogAction.reason == 1 && this.isMaskTapToCloseEnabled) { this.promptAction.closeCustomDialog(this.contentNode) } }, onDidAppear: this.onDidAppearCallback ? this.onDidAppearCallback : () => { }, onDidDisappear: this.onDidDisappearCallback ? this.onDidDisappearCallback : () => { }, onWillAppear: this.onWillAppearCallback ? this.onWillAppearCallback : () => { }, onWillDisappear: this.onWillDisappearCallback ? this.onWillDisappearCallback : () => { }, }); } catch (error) { // 错误处理 let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(OpenCustomDialog args error code is ${code}, message is ${message}); } return this; } }

class MyToastInfo extends MyPromptInfo { public message: string = “”

constructor(message: string) { super() this.message = message } }

@Builder function myToastView(data: MyToastInfo) { MyToastView({ dialogID: data.dialogID, message: data.message }) }

@ObservedV2 class ToastBean { message: string = “” @Trace isShow: boolean = true

constructor(message: string) { this.message = message } }

@Component struct MyToastView { @Prop dialogID: string @Prop message: string

aboutToAppear(): void { }

build() { Column() { Text(‘局部弹窗:’) Text(${<span class="hljs-keyword">this</span>.message}) .fontSize(‘36lpx’) .fontColor(Color.White) .backgroundColor("#B2ff0000") .borderRadius(8) .constraintSize({ maxWidth: ‘80%’ }) .padding({ bottom: ‘28lpx’, left: ‘60lpx’, right: ‘60lpx’, top: ‘28lpx’ }) .margin(5) Button(‘关闭弹窗’).onClick(()=>{ getContext(this).eventHub.emit(this.dialogID, “关闭弹窗”) }) }.width(‘300lpx’).height(‘500lpx’).backgroundColor(Color.Orange).borderRadius(10) } } <button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

src/main/ets/pages/Page01.ets

import { MyPromptActionUtil } from ‘…/common/MyPromptActionUtil’
import { promptAction } from ‘@kit.ArkUI’

@Entry @Component struct Page01 {

build() { Column() { Button(‘显示Toast’).onClick(() => { MyPromptActionUtil.showToast(随机数:${<span class="hljs-keyword">this</span>.getRandomInt(<span class="hljs-number">1</span>, <span class="hljs-number">100</span>)}) }) Button(‘弹窗显示时,也可以与此按钮交互’).onClick(()=>{ promptAction.showToast({message:‘哈哈123’}) }) } .width(‘100%’) .height(‘100%’) } getRandomInt(min: number, max: number): number { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

楼主可以参考子窗口是否可行

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

可以看下promptAction

可以试一下UIContext.bindSheet
回到顶部