HarmonyOS Next-鸿蒙中封装一个自定义全局弹窗
要先拿到窗口实例在拿到窗口的上下文才能通过拿到全局自定义弹出框openCustomDialog(组件,弹窗配置对象)打开弹窗closeCustomDialog(组件)关闭弹窗// 拿到当前最顶层的窗口// 拿到UIContext// 拿到当前窗口的全局弹窗// 创建一个组件// 弹窗配置对象// 将key/value写入到map中promptAction.openCustomDialog(cont
·
与昨天效果相似,区别在于,一个是新开一个窗口,一个是显示当前窗口的全局弹窗
思路:
- 创建一个名为ManagerFinal的类。
- 定义map状态用来存储弹窗组件,便于后续关闭弹窗
- 获取当前窗口需要用到上下文,没有就在当前环境中获取
- 定义showArt方法用于显示弹窗:
- 获取当前窗口拿到UIContext,在通过UIContext拿到全局弹窗
- 创建一个组件显示弹窗的内容,并把组件存到map中
- 打开弹窗
- 定义closeArt方法用于关闭弹窗:
- 获取当前窗口拿到UIContext,在通过UIContext拿到全局弹窗
- 拿到当前组件关闭弹窗,清除map中的组件
代码:
下面有代码中api的大致意思
import { AdvertClass } from '../viewmodels'
import { ComponentContent, promptAction, window } from '@kit.ArkUI'
import { util } from '@kit.ArkTS'
// 展示弹窗的结构
@Builder
function uiBuilder(uiObj: AdvertClass) {
// 弹窗内容...
}
export class ManagerFinal {
context?: Context
// 所有的弹窗都放到这个map中 通过name来标识
private map: Map<string, ComponentContent<AdvertClass>> = new Map()
async showArt(uiObj: AdvertClass) {
// 生成一个name
let name: string = `dialog_${util.generateRandomUUID()}`
// 拿到当前最顶层的窗口
const mainWin = await window.getLastWindow(this.context || getContext())
let uiContext = mainWin.getUIContext() // 拿到UIContext
let promptAction = uiContext.getPromptAction() // 拿到当前窗口的全局提示框
uiObj.dialogName = name // 将dialog的弹窗名称传到builder中,方便再builder中关闭弹窗
// 创建一个组件
let contentNode = new ComponentContent(uiContext, wrapBuilder(AdBuilder), uiObj)
let options: promptAction.BaseDialogOptions = { // 弹窗配置对象
alignment: DialogAlignment.Center, // 居中
autoCancel: false // 不自动关闭
}
this.map.set(name, contentNode) // 将key/value写入到map中
promptAction.openCustomDialog(contentNode, options) // 打开弹窗
}
async closeArt(name: string) {
if (name) {
const mainWin = await window.getLastWindow(this.context || getContext())
let uiContext = mainWin.getUIContext()
let promptAction = uiContext.getPromptAction()
promptAction.closeCustomDialog(this.map.get(name)) // 关闭弹窗
// 清理map
this.map.delete(name) // 删除已经关闭的弹窗
}
}
}
// 暴露类
export const managerFinal = new ManagerFinal()
知识点:
1. 获取最上层的窗口window.getLastWindow
- getLastWindow(ctx: BaseContext): Promise<Window>
- 获取当前应用内最上层的子窗口,若无应用子窗口,则返回应用主窗口,使用Promise异步回调。
2. 获取当前窗口的上下文getUIContext
- window实例.getUIContext(): UIContext
- 获取UIContext实例。
- 就是里面存储了当前窗口的很多东西,详细看官网
|
类型 |
说明 |
|
返回UIContext实例对象。 |
3. 编程式创建一个组件ComponentContent
- constructor(uiContext: UIContext, builder: WrappedBuilder<[]>)
- 创建一个组件
|
uiContext |
是 |
创建对应节点时候所需要的UI上下文。 |
|
|
builder |
是 |
封装不带参builder函数的WrappedBuilder对象。 |
// 创建一个组件
// (上下文,全局builder,builder所需参数)
let contentNode = new ComponentContent(uiContext, wrapBuilder(AdBuilder), uiObj)
4. 全局自定义弹出框promptAction
要先拿到窗口实例在拿到窗口的上下文才能通过getPromptAction()拿到全局自定义弹出框
- openCustomDialog(组件,弹窗配置对象) 打开弹窗
- closeCustomDialog(组件) 关闭弹窗
// 拿到当前最顶层的窗口
const mainWin = await window.getLastWindow(this.context || getContext())
// 拿到UIContext
let uiContext = mainWin.getUIContext()
// 拿到当前窗口的全局弹窗
let promptAction = uiContext.getPromptAction()
// 创建一个组件
let contentNode = new ComponentContent(uiContext, wrapBuilder(AdBuilder), uiObj)
// 弹窗配置对象
let options: promptAction.BaseDialogOptions = {
alignment: DialogAlignment.Center,
autoCancel: false
}
// 将key/value写入到map中
this.map.set(name, contentNode)
promptAction.openCustomDialog(contentNode, options) // 打开弹窗
promptAction.closeCustomDialog(this.map.get(name)) // 关闭弹窗
效果:
广告场景

都可灵活,结构看着写,点击关闭、倒计时关闭随便写...
结构代码:
// 弹窗的结构
@Builder
function AdBuilder(ad: AdvertClass) {
Column() {
Column({space: 30}) {
Text('广告招租')
.fontSize(60)
Image($r('app.media.caixukun'))
.width(100)
.height(100)
}
.justifyContent(FlexAlign.Center)
.width("100%")
.height("100%")
Row() {
Image($r("app.media.ic_btn_close"))
.width(14)
.aspectRatio(1)
.fillColor("#ccc")
}
.width(30)
.aspectRatio(1)
.justifyContent(FlexAlign.Center)
.borderRadius(15)
.position({ right: 20, top: 40 })
.border({
color: '#ff343232',
width: 2
})
.margin({
top: 40
})
.onClick(() => {
if (ad.dialogName) {
adManagerFinal.closeAd(ad.dialogName) // 关闭弹窗
}
})
}
.width(ad.isFull ? "100%" : "80%")
.height(ad.isFull ? "100%" : "50%")
}
更多推荐


所有评论(0)