1# 不依赖UI组件的全局气泡提示 (openPopup) 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @liyi0309--> 5<!--Designer: @liyi0309--> 6<!--Tester: @lxl007--> 7<!--Adviser: @HelloCrease--> 8 9[气泡提示(Popup)](arkts-popup-and-menu-components-popup.md)在使用时依赖绑定UI组件,否则无法使用。从API version 18开始,可以通过使用全局接口[openPopup](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#openpopup18)的方式,在无UI组件的场景下直接或封装使用,例如在事件回调中使用或封装后对外提供能力。 10 11## 弹出气泡 12 13通过[openPopup](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#openpopup18)可以弹出气泡。 14 15 ```ts 16 promptAction.openPopup(contentNode, { id: targetId }, { 17 enableArrow: true 18 }) 19 .then(() => { 20 console.info('openPopup success'); 21 }) 22 .catch((err: BusinessError) => { 23 console.error('openPopup error: ' + err.code + ' ' + err.message); 24 }) 25 ``` 26 27### 创建ComponentContent 28 29 通过调用openPopup接口弹出其气泡,需要提供用于定义自定义弹出框的内容[ComponentContent](../reference/apis-arkui/js-apis-arkui-ComponentContent.md)。其中,wrapBuilder(buildText)封装自定义组件,new Params(this.message)是自定义组件的入参,可以缺省,也可以传入基础数据类型。 30 31 ```ts 32 private contentNode: ComponentContent<Object> = new ComponentContent(uiContext, wrapBuilder(buildText), this.message); 33 ``` 34 35 如果在wrapBuilder中包含其他组件(例如:[Popup](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Popup.md)、[Chip](../reference/apis-arkui/arkui-ts/ohos-arkui-advanced-Chip.md)组件),则[ComponentContent](../reference/apis-arkui/js-apis-arkui-ComponentContent.md#componentcontent-1)应采用带有四个参数的构造函数constructor,其中options参数应传递{ nestingBuilderSupported: true }。 36 37 ```ts 38 @Builder 39 export function buildText(params: Params) { 40 Popup({ 41 // 类型设置图标内容 42 icon: { 43 image: $r('app.media.app_icon'), 44 width: 32, 45 height: 32, 46 fillColor: Color.White, 47 borderRadius: 10 48 } as PopupIconOptions, 49 // 设置文字内容 50 title: { 51 text: `This is a Popup title 1`, 52 fontSize: 20, 53 fontColor: Color.Black, 54 fontWeight: FontWeight.Normal 55 } as PopupTextOptions, 56 // 设置文字内容 57 message: { 58 text: `This is a Popup message 1`, 59 fontSize: 15, 60 fontColor: Color.Black 61 } as PopupTextOptions, 62 // 设置按钮内容 63 buttons: [{ 64 text: 'confirm', 65 action: () => { 66 console.info('confirm button click'); 67 }, 68 fontSize: 15, 69 fontColor: Color.Black, 70 }, 71 { 72 text: 'cancel', 73 action: () => { 74 console.info('cancel button click'); 75 }, 76 fontSize: 15, 77 fontColor: Color.Black 78 },] as [PopupButtonOptions?, PopupButtonOptions?] 79 }) 80 } 81 82 let contentNode: ComponentContent<Object> = new ComponentContent(uiContext, wrapBuilder(buildText), this.message, { nestingBuilderSupported: true }); 83 ``` 84 85 86### 绑定组件信息 87 88 通过调用openPopup接口弹出气泡,需要提供绑定组件的信息[TargetInfo](../reference/apis-arkui/arkts-apis-uicontext-i.md#targetinfo18)。若未传入有效的target,则无法弹出气泡。 89 90 ```ts 91 let frameNode: FrameNode | null = this.ctx.getFrameNodeByUniqueId(this.getUniqueId()); 92 let targetId = frameNode?.getChild(0)?.getUniqueId(); 93 ``` 94 95### 设置弹出气泡样式 96 97 通过调用openPopup接口弹出气泡,可以设置[PopupCommonOptions](../reference/apis-arkui/arkui-ts/ts-universal-attributes-popup.md#popupcommonoptions18类型说明)属性调整气泡样式。 98 99 ```ts 100 private options: PopupCommonOptions = { enableArrow: true }; 101 ``` 102 103## 更新气泡样式 104 105通过[updatePopup](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#updatepopup18)可以更新气泡的样式。支持全量更新和增量更新其气泡样式,不支持更新showInSubWindow、focusable、onStateChange、onWillDismiss和transition。 106 107 ```ts 108 promptAction.updatePopup(contentNode, { 109 enableArrow: false 110 }, true) 111 .then(() => { 112 console.info('updatePopup success'); 113 }) 114 .catch((err: BusinessError) => { 115 console.error('updatePopup error: ' + err.code + ' ' + err.message); 116 }) 117 ``` 118 119## 关闭气泡 120 121通过调用[closePopup](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#closepopup18)可以关闭气泡。 122 123 ```ts 124 promptAction.closePopup(contentNode) 125 .then(() => { 126 console.info('closePopup success'); 127 }) 128 .catch((err: BusinessError) => { 129 console.error('closePopup error: ' + err.code + ' ' + err.message); 130 }) 131 ``` 132 133> **说明:** 134> 135> 由于[updatePopup](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#updatepopup18)和[closePopup](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#closepopup18)依赖content来更新或者关闭指定的气泡,开发者需自行维护传入的content。 136 137 138## 在HAR包中使用全局气泡提示 139 140以下示例通过[HAR](../quick-start/har-package.md)包封装一个Popup,从而对外提供气泡的弹出、更新和关闭能力。 141 142```ts 143// library/src/main/ets/components/MainPage.ets 144 145import { BusinessError } from '@kit.BasicServicesKit'; 146import { ComponentContent, TargetInfo, PromptAction } from '@kit.ArkUI'; 147 148export class PromptActionClass { 149 private promptAction: PromptAction | null = null; 150 private contentNode: ComponentContent<Object> | null = null; 151 private options: PopupCommonOptions | null = null; 152 private target: TargetInfo | null = null; 153 private isPartialUpdate: boolean = false; 154 155 public setPromptAction(promptAction: PromptAction) { 156 this.promptAction = promptAction; 157 } 158 159 public setContentNode(node: ComponentContent<Object>) { 160 this.contentNode = node; 161 } 162 163 public setTarget(target: TargetInfo) { 164 this.target = target; 165 } 166 167 public setOptions(options: PopupCommonOptions) { 168 this.options = options; 169 } 170 171 public setIsPartialUpdate(isPartialUpdate: boolean) { 172 this.isPartialUpdate = isPartialUpdate; 173 } 174 175 public openPopup() { 176 if (this.promptAction != null) { 177 this.promptAction.openPopup(this.contentNode, this.target, this.options) 178 .then(() => { 179 console.info('openPopup success'); 180 }) 181 .catch((err: BusinessError) => { 182 console.error('openPopup error: ' + err.code + ' ' + err.message); 183 }) 184 } 185 } 186 187 public closePopup() { 188 if (this.promptAction != null) { 189 this.promptAction.closePopup(this.contentNode) 190 .then(() => { 191 console.info('closePopup success'); 192 }) 193 .catch((err: BusinessError) => { 194 console.error('closePopup error: ' + err.code + ' ' + err.message); 195 }) 196 } 197 } 198 199 public updatePopup(options: PopupCommonOptions) { 200 if (this.promptAction != null) { 201 this.promptAction.updatePopup(this.contentNode, options, this.isPartialUpdate) 202 .then(() => { 203 console.info('updatePopup success'); 204 }) 205 .catch((err: BusinessError) => { 206 console.error('updatePopup error: ' + err.code + ' ' + err.message); 207 }) 208 } 209 } 210} 211``` 212 213```ts 214// entry/src/main/ets/pages/Index.ets 215 216import { PromptActionClass } from "library"; 217import { ComponentContent, PromptAction } from '@kit.ArkUI'; 218 219class Params { 220 text: string = ""; 221 promptActionClass: PromptActionClass = new PromptActionClass(); 222 223 constructor(text: string, promptActionClass: PromptActionClass) { 224 this.text = text; 225 this.promptActionClass = promptActionClass; 226 } 227} 228 229@Builder 230function buildText(params: Params) { 231 Column() { 232 Text(params.text) 233 .fontSize(20) 234 .margin({ top: 10 }) 235 Button('Update') 236 .margin({ top: 10 }) 237 .width(100) 238 .onClick(() => { 239 params.promptActionClass.updatePopup({ 240 enableArrow: false, 241 }); 242 }) 243 Button('Close') 244 .margin({ top: 10 }) 245 .width(100) 246 .onClick(() => { 247 params.promptActionClass.closePopup(); 248 }) 249 }.width(130).height(150) 250} 251 252@Entry 253@Component 254struct Index { 255 @State message: string = "hello"; 256 private uiContext: UIContext = this.getUIContext(); 257 private promptAction: PromptAction = this.uiContext.getPromptAction(); 258 private promptActionClass: PromptActionClass = new PromptActionClass(); 259 private targetId: number = 0; 260 private contentNode: ComponentContent<Object> = 261 new ComponentContent(this.uiContext, wrapBuilder(buildText), new Params(this.message, this.promptActionClass)); 262 private options: PopupCommonOptions = { enableArrow: true }; 263 264 build() { 265 Column() { 266 Button("openPopup") 267 .margin({ top: 50, left: 100 }) 268 .onClick(() => { 269 let frameNode: FrameNode | null = this.uiContext.getFrameNodeByUniqueId(this.getUniqueId()); 270 let targetId = frameNode?.getChild(0)?.getUniqueId(); 271 if (targetId == undefined) { 272 this.targetId = 0; 273 } else { 274 this.targetId = targetId; 275 } 276 this.promptActionClass.setPromptAction(this.promptAction); 277 this.promptActionClass.setContentNode(this.contentNode); 278 this.promptActionClass.setOptions(this.options); 279 this.promptActionClass.setIsPartialUpdate(false); 280 this.promptActionClass.setTarget({ id: this.targetId }); 281 this.promptActionClass.openPopup(); 282 }) 283 } 284 } 285} 286``` 287 288 289