这里梳理一下鸿蒙自定义 Toast 提示实现思路。一般在应用里一些错误信息都会用到 Toast 提示,而这些相似的提示功能不可能在需要的每一个页面里都重复写一遍,最方便的方式还是用一个全局对象进行管理,那么,这里就需要一个通用展示 Toast 提示的地方,这里可以直接创建一个子窗口,子窗口加载自定义提示内容,应用在需要提示的地方用全局对象去操作子窗口即可。
一、效果展示
二、代码实现
调用下面的几行实例代码就实现上面的提示效果,而无需为每个 page 页面进行重复的页面搭建
WSLToastShow({ content: '清理中',toastType: ToastType.ToastProgress })
setTimeout(()=>{
WSLToastShow({ content: '清除成功',toastType: ToastType.ToastNormalNoShowDefaultTitle })
},2000)
上面说明了 Toast 是在子窗口下进行展示的,那么,第一步肯定是要创建子窗口并把它展示在主屏幕上。
1、注册 window.WindowStage
因为后面需要用到 WindowStage 这个实例对象,那么,在项目的入口文件 EntryAbility.ets 里保存一下
import { WindowManager } from '@kit.SpeechKit';
onWindowStageCreate(windowStage: window.WindowStage): void {
// 保存当前的主窗口
WindowManager.setWindowStage(windowStage)
}
2、创建子窗口
import { WindowManager } from '@kit.SpeechKit';
createSubWindow(subWindowName: string = 'WSLCustomSubWindow',page: string){
WindowManager.getWindowStage().createSubWindow(subWindowName,(err,subWindow)=> {
WindowManager.getWindowStage().getMainWindow().then((mainWindow)=>{
let screenWidth = mainWindow.getWindowProperties().windowRect.width
let screenHeight = mainWindow.getWindowProperties().windowRect.height
subWindow.setUIContent(page)
subWindow.resize(screenWidth,screenHeight)
subWindow.setWindowTouchable(false)
subWindow.showWindow((err)=>{
if(!err.code){
try {
subWindow.setWindowBackgroundColor('#00000000')
} catch (e) {
}
}
})
})
}
})
}
WindowManager.getWindowStage().createSubWindow 来创建子窗口,需要设置子窗口的名字,后面会用于销毁对应的子窗口。在创建回调方法里设置子窗口的位置、大小及加载的页面路径,subWindow.setWindowTouchable(false) 方法设置子窗口不可进行手势交互,这意味着展示过程中,用户仍然能进行其他操作,如果某些操作是要完全等待的操作,那么,可以将手势交互打开。最后,设置窗口的背景颜色为完全透明,剩下的提示效果就是在 page 页面里进行搭建了。
3、销毁子窗口
提示成功了,或者有新的提示内容,那么,就销毁之前子窗口。(注:其实不需要每次都去销毁它,可以用懒加载的方式创建子窗口,在后面需要用到的地方进行子窗口内部页面的内容展示与隐藏)这里还是用的是完全销毁操作,简单粗暴。
function WSLToastDismiss(subWindowName:string,callBack?:AsyncCallback<void>){
try {
window.findWindow(subWindowName).destroyWindow(callBack)
} catch (e) {
callBack && callBack(null)
}
}
调用 window.findWindow(subWindowName).destroyWindow(callBack) 方法 销毁对应的名字的子窗口。
4、提示内容的传递
主窗口页面操作子窗口页面的展示内容,那么简单的方式就是用 AppStorageV2.connect 实现应用内数据共享,在打开子窗口前进行新数据的替换,等到子窗口加载 page 页面时,拿到最新的数据进行展示。
//展示新的弹窗提供内容源
const saveModel = AppStorageV2.connect(ToastModel, () => new ToastModel())!
三、总结与思考
这里主要熟悉一下,子窗口的创建、加载页面、销毁等操作,在子窗口下操作可减少每次提示需要的相同逻辑,提示的样式及操作,又完全可以自定义。对于系统的 CustomDialogController 自定义弹窗,需要传入一个 @Builder 修饰的构建方法参数,用法不复杂,但不同页面展示的时候就会导致重复代码创建,对于相同的功能反而有点啰嗦了。希望能帮助到大家[抱拳][抱拳][抱拳]