1# Managing Overlays (OverlayManager) 2 3Overlays, implemented using **OverlayManager**, are used to display custom UI content on top of a page, but below such components as created through **Dialog**, **Popup**, **Menu**, **BindSheet**, **BindContentCover**, and **Toast**. These overlays are confined to the safe area of the current window. Overlays are applicable to scenarios such as persistent floating elements. 4 5 6 7You can use the [getOverlayManager](../reference/apis-arkui/js-apis-arkui-UIContext.md#getoverlaymanager12) API in [UIContext](../reference/apis-arkui/js-apis-arkui-UIContext.md#uicontext) to obtain the [OverlayManager](../reference/apis-arkui/js-apis-arkui-UIContext.md#overlaymanager12) object associated with the current UI context, and then call the corresponding APIs using this object. 8 9## Specifications Constraints 10 11* The nodes on **OverlayManager** are above the page level, but below such components as created through **Dialog**, **Popup**, **Menu**, **BindSheet**, **BindContentCover**, and **Toast**. 12* There is no default animation when nodes on **OverlayManager** appear or disappear. 13* The drawing method inside and outside the safe area of nodes on **OverlayManager** is consistent with that of the page, and the keyboard avoidance method is also the same as that of the page. 14* For properties related to **OverlayManager**, you are advised to use AppStorage for global storage across the application to prevent changes in property values when switching pages, which could lead to service errors. 15 16## Managing Overlays 17 18With **OverlayManager**, you can add a specified node ([addComponentContent](../reference/apis-arkui/js-apis-arkui-UIContext.md#addcomponentcontent12)), remove a specified node ([removeComponentContent](../reference/apis-arkui/js-apis-arkui-UIContext.md#removecomponentcontent12)), show all nodes ([showAllComponentContents](../reference/apis-arkui/js-apis-arkui-UIContext.md#showallcomponentcontents12)), and hide all nodes ([hideAllComponentContents](../reference/apis-arkui/js-apis-arkui-UIContext.md#hideallcomponentcontents12)). 19 20```ts 21import { ComponentContent, OverlayManager, router } from '@kit.ArkUI'; 22 23class Params { 24 text: string = "" 25 offset: Position 26 constructor(text: string, offset: Position) { 27 this.text = text 28 this.offset = offset 29 } 30} 31@Builder 32function builderText(params: Params) { 33 Column() { 34 Text(params.text) 35 .fontSize(30) 36 .fontWeight(FontWeight.Bold) 37 }.offset(params.offset) 38} 39 40@Entry 41@Component 42struct OverlayExample { 43 @State message: string = 'ComponentContent'; 44 private uiContext: UIContext = this.getUIContext() 45 private overlayNode: OverlayManager = this.uiContext.getOverlayManager() 46 @StorageLink('contentArray') contentArray: ComponentContent<Params>[] = [] 47 @StorageLink('componentContentIndex') componentContentIndex: number = 0 48 @StorageLink('arrayIndex') arrayIndex: number = 0 49 @StorageLink("componentOffset") componentOffset: Position = {x: 0, y: 80} 50 51 build() { 52 Column() { 53 Button("++componentContentIndex: " + this.componentContentIndex).onClick(()=>{ 54 ++this.componentContentIndex 55 }) 56 Button("--componentContentIndex: " + this.componentContentIndex).onClick(()=>{ 57 --this.componentContentIndex 58 }) 59 Button("Add ComponentContent" + this.contentArray.length).onClick(()=>{ 60 let componentContent = new ComponentContent( 61 this.uiContext, wrapBuilder<[Params]>(builderText), 62 new Params(this.message + (this.contentArray.length), this.componentOffset) 63 ) 64 this.contentArray.push(componentContent) 65 this.overlayNode.addComponentContent(componentContent, this.componentContentIndex) 66 }) 67 Button("++arrayIndex: " + this.arrayIndex).onClick(()=>{ 68 ++this.arrayIndex 69 }) 70 Button("--arrayIndex: " + this.arrayIndex).onClick(()=>{ 71 --this.arrayIndex 72 }) 73 Button("Delete ComponentContent" + this.arrayIndex).onClick(()=>{ 74 if (this.arrayIndex >= 0 && this.arrayIndex < this.contentArray.length) { 75 let componentContent = this.contentArray.splice(this.arrayIndex, 1) 76 this.overlayNode.removeComponentContent(componentContent.pop()) 77 } else { 78 console.info("Invalid arrayIndex.") 79 } 80 }) 81 Button("Show ComponentContent" + this.arrayIndex).onClick(()=>{ 82 if (this.arrayIndex >= 0 && this.arrayIndex < this.contentArray.length) { 83 let componentContent = this.contentArray[this.arrayIndex] 84 this.overlayNode.showComponentContent(componentContent) 85 } else { 86 console.info("Invalid arrayIndex.") 87 } 88 }) 89 Button("Hide ComponentContent" + this.arrayIndex).onClick(()=>{ 90 if (this.arrayIndex >= 0 && this.arrayIndex < this.contentArray.length) { 91 let componentContent = this.contentArray[this.arrayIndex] 92 this.overlayNode.hideComponentContent(componentContent) 93 } else { 94 console.info("Invalid arrayIndex.") 95 } 96 }) 97 Button("Show All ComponentContent").onClick(()=>{ 98 this.overlayNode.showAllComponentContents() 99 }) 100 Button("Hide All ComponentContent").onClick(()=>{ 101 this.overlayNode.hideAllComponentContents() 102 }) 103 104 Button("Go").onClick(()=>{ 105 router.pushUrl({ 106 url: 'pages/Second' 107 }) 108 }) 109 } 110 .width('100%') 111 .height('100%') 112 } 113} 114``` 115The following example shows how to display a floating bubble that always stays on the left side of the screen, and clicking it displays an alert dialog box. 116 117```ts 118import { ComponentContent, OverlayManager } from '@kit.ArkUI'; 119 120class Params { 121 context: UIContext 122 offset: Position 123 constructor(context: UIContext, offset: Position) { 124 this.context = context 125 this.offset = offset 126 } 127} 128@Builder 129function builderOverlay(params: Params) { 130 Column() { 131 Stack(){ 132 }.width(50).height(50).backgroundColor(Color.Yellow).position(params.offset).borderRadius(50) 133 .onClick(() => { 134 params.context.showAlertDialog( 135 { 136 title: 'title', 137 message: 'text', 138 autoCancel: true, 139 alignment: DialogAlignment.Center, 140 gridCount: 3, 141 confirm: { 142 value: 'button', 143 action: () => {} 144 }, 145 cancel: () => {} 146 } 147 ) 148 }) 149 }.focusable(false).width('100%').height('100%').hitTestBehavior(HitTestMode.Transparent) 150} 151 152@Entry 153@Component 154struct OverlayExample { 155 @State message: string = 'ComponentContent'; 156 private uiContext: UIContext = this.getUIContext() 157 private overlayNode: OverlayManager = this.uiContext.getOverlayManager() 158 private overlayContent:ComponentContent<Params>[] = [] 159 controller: TextInputController = new TextInputController() 160 161 aboutToAppear(): void { 162 let uiContext = this.getUIContext(); 163 let componentContent = new ComponentContent( 164 this.uiContext, wrapBuilder<[Params]>(builderOverlay), 165 new Params(uiContext, {x:0, y: 100}) 166 ) 167 this.overlayNode.addComponentContent(componentContent, 0) 168 this.overlayContent.push(componentContent) 169 } 170 171 aboutToDisappear(): void { 172 let componentContent = this.overlayContent.pop() 173 this.overlayNode.removeComponentContent(componentContent) 174 } 175 176 build() { 177 Column() { 178 179 } 180 .width('100%') 181 .height('100%') 182 } 183} 184 185``` 186