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