【HarmonyOS】封装可以同时显示多个toast的工具类

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 = '' ; for ( let i = 0 ; i < length ; i ++ ) { const randomIndex = Math . floor ( Math . random ( ) * characters . length ) ; result += characters . charAt ( randomIndex ) ; } return 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 ( ) } ) } else { //当前正在显示toast getContext ( ) . eventHub . emit ( MyPromptActionUtil . myDialogPromptActionUtil . dialogID , { msg : message } ) } } 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 { @State toast_info_list : ToastBean [ ] = [ ] @Prop dialogID : string @Prop message : string aboutToAppear ( ) : void { this . toast_info_list . push ( new ToastBean ( this . message ) ) getContext ( ) . eventHub . on ( this . dialogID , ( data : object ) => { if ( data [ 'msg' ] ) { this . toast_info_list . push ( new ToastBean ( data [ 'msg' ] ) ) } } ) } build ( ) { Column ( ) { ForEach ( this . toast_info_list , ( item : ToastBean ) => { Text ( item . message ) . fontSize ( '36lpx' ) . fontColor ( Color . White ) . backgroundColor ( "#B2ff0000" ) . borderRadius ( 8 ) . constraintSize ( { maxWidth : '80%' } ) . padding ( { bottom : '28lpx' , left : '60lpx' , right : '60lpx' , top : '28lpx' } ) . margin ( 5 ) . visibility ( item . isShow ? Visibility . Visible : Visibility . None ) . onVisibleAreaChange ( [ 0.0 , 1.0 ] , ( isVisible : boolean , currentRatio : number ) => { console . info ( 'Test Text isVisible: ' + isVisible + ', currentRatio:' + currentRatio ) if ( isVisible && currentRatio >= 1.0 ) { setTimeout ( ( ) => { item . isShow = false } , 2000 ) } } ) . animation ( { duration : 200 , onFinish : ( ) => { console . info ( '==== onFinish' ) //动画结束后,判断数组是否已全部为隐藏状态,是的话证明所有toast内容都展示完成,可以释放全局弹窗了 let isAnimAll = true for ( let i = 0 ; i < this . toast_info_list . length ; i ++ ) { if ( this . toast_info_list [ i ] . isShow == true ) { //至少有一个正在显示 isAnimAll = false break ; } } if ( isAnimAll ) { console . info ( '已展示完全部toast,为了性能,关闭弹窗释放view' ) getContext ( this ) . eventHub . emit ( this . dialogID , "关闭弹窗" ) } } } ) . transition ( TransitionEffect . OPACITY . animation ( { duration : 200 } ) ) } ) } } }
import { MyPromptActionUtil } from '../common/MyPromptActionUtil' @Entry @Component struct Page01 { build ( ) { Column ( ) { Button ( '显示Toast' ) . onClick ( ( ) => { MyPromptActionUtil . showToast ( ` 随机数: ${ this . getRandomInt ( 1 , 100 ) } ` ) } ) } . 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 ; } }
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/24984661/viewspace-3107431/ ,如需转载,请注明出处,否则将追究法律责任。