1# 弹出框蒙层控制 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @houguobiao--> 5<!--Designer: @houguobiao--> 6<!--Tester: @lxl007--> 7<!--Adviser: @HelloCrease--> 8 9开发者对弹出框的定制不仅限于弹出框里的内容,对弹出框蒙层的定制需求也逐渐增加。本文介绍ArkUI弹出框的蒙层控制,包括点击蒙层时是否消失、蒙层区域、蒙层颜色和蒙层动画等特性。 10 11## 使用约束 12 13ArkUI提供多种弹出框,不同类型的弹出框具备不同的蒙层定制能力。详情请参阅下表: 14 15| 接口&组件 |autoCancel|maskRect|isModal|immersiveMode| 16| ----------------- | ------ |------ |------ |------ | 17|[openCustomDialog](arkts-uicontext-custom-dialog.md)|支持|支持|支持|支持| 18|[openCustomDialogWithController](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#opencustomdialogwithcontroller18)|支持|支持|支持|支持| 19|[presentCustomDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#presentcustomdialog18)|支持|支持|支持|支持| 20|[updateCustomDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#updatecustomdialog12)|支持|不支持|不支持|不支持| 21|[CustomDialog](arkts-common-components-custom-dialog.md)|支持|支持|支持|支持| 22|[showDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showdialog)|不支持|支持|支持|支持| 23|[showAlertDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showalertdialog)|支持|支持|支持|支持| 24|[showActionSheet](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showactionsheet)|支持|支持|支持|支持| 25|[showActionMenu](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showactionmenu11)|不支持|不支持|支持|支持| 26|[showDatePickerDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showdatepickerdialog)|不支持|支持|不支持|不支持| 27|[CalendarPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-calendarpicker-dialog.md)|不支持|不支持|不支持|不支持| 28|[showTimePickerDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showtimepickerdialog)|不支持|支持|不支持|不支持| 29|[showTextPickerDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showtextpickerdialog)|不支持|支持|不支持|不支持| 30 31> **说明:** 32> 33> - 设置autoCancel参数,可控制弹出框蒙层被点击时是否消失。 34> 35> - 设置maskRect参数,可定制弹出框的蒙层的大小和位置进行定制。此外,蒙层范围内的事件无法透传,而蒙层范围外的事件可以透传。 36> 37> - 设置isModal参数,可定制弹出框的模态状态:非模态弹出框无蒙层,支持与周围组件交互;模态弹出框有蒙层,禁止与周围组件交互。 38> 39> - 当levelMode属性设置为LevelMode.EMBEDDED时,设置immersiveMode参数,可定制弹出框蒙层是否延伸至状态栏及导航栏。 40 41| 接口&组件 | maskColor | transition | maskTransition | 42| ------------------------------------------------------------ | --------- | ----------------------------------------------- | -------------- | 43| [openCustomDialog](arkts-uicontext-custom-dialog.md) | 支持 | 支持 | 支持 | 44| [openCustomDialogWithController](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#opencustomdialogwithcontroller18) | 支持 | 支持 | 支持 | 45| [presentCustomDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#presentcustomdialog18) | 支持 | 支持 | 支持 | 46| [updateCustomDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#updatecustomdialog12) | 支持 | 不支持 | 不支持 | 47| [CustomDialog](arkts-common-components-custom-dialog.md) | 支持 | 不支持(可由openAnimation和closeAnimation替代) | 不支持 | 48| [showDialog](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showdialog) | 不支持 | 不支持 | 不支持 | 49| [showAlertDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showalertdialog) | 不支持 | 支持 | 不支持 | 50| [showActionSheet](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showactionsheet) | 不支持 | 支持 | 不支持 | 51| [showActionMenu](../reference/apis-arkui/arkts-apis-uicontext-promptaction.md#showactionmenu11) | 不支持 | 不支持 | 不支持 | 52| [showDatePickerDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showdatepickerdialog) | 不支持 | 不支持 | 不支持 | 53| [CalendarPickerDialog](../reference/apis-arkui/arkui-ts/ts-methods-calendarpicker-dialog.md) | 不支持 | 不支持 | 不支持 | 54| [showTimePickerDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showtimepickerdialog) | 不支持 | 不支持 | 不支持 | 55| [showTextPickerDialog](../reference/apis-arkui/arkts-apis-uicontext-uicontext.md#showtextpickerdialog) | 不支持 | 不支持 | 不支持 | 56 57> **说明:** 58> 59> - 设置maskColor参数,可定制弹出框蒙层的颜色。 60> 61> - 设置openAnimation参数,可定制弹出框的进入动画,同时影响蒙层动画。该接口仅支持简单的动画设置,不支持复杂动画定制。 62> 63> - 设置closeAnimation参数,可定制弹出框的退出动画,同时影响蒙层动画。该接口仅支持简单的动画设置,不支持复杂动画定制。 64> 65> - 设置transition参数,可定制弹出框的进入和退出动画,同时影响蒙层动画。 66> 67> - 设置maskTransition参数,可定制弹出框的蒙层动画。 68 69 70## 弹出框蒙层显隐控制 71 72通过autoCancel,isModal展示弹出框在蒙层显隐控制方面的能力。 73 74设置autoCancel为false,取消默认点击蒙层时弹窗消失。 75 76```ts 77// xxx.ets 78 autoCancelOpt: promptAction.CustomDialogOptions = { 79 builder: () => { 80 this.myBuilder(); 81 }, 82 autoCancel: false, 83 } as promptAction.CustomDialogOptions; 84 85 Button("openCustomDialog autoCancel:false") 86 .width('100%') 87 .margin({ top: 10 }) 88 .onClick(() => { 89 this.getUIContext().getPromptAction().openCustomDialog(this.autoCancelOpt) 90 }) 91``` 92  93 94设置isModal为false,将默认的模态弹出框变为非模态弹出框。 95```ts 96// xxx.ets 97modalOpt: promptAction.CustomDialogOptions = { 98 builder: () => { 99 this.myBuilder(); 100 }, 101 isModal: false, 102} as promptAction.CustomDialogOptions; 103 104Button("openCustomDialog isModal:false") 105 .width('100%') 106 .margin({ top: 10 }) 107 .onClick(() => { 108 this.getUIContext().getPromptAction().openCustomDialog(this.modalOpt) 109 }) 110``` 111  112 113 114## 弹出框蒙层样式控制 115 116该示例通过maskRect、immersiveMode和maskColor展示弹出框在蒙层样式控制方面的能力。 117 118 119设置maskRect和maskColor,实现蒙层区域和蒙层颜色的设置。 120 121```ts 122// xxx.ets 123 maskOpt: promptAction.CustomDialogOptions = { 124 builder: () => { 125 this.myBuilder(); 126 }, 127 maskRect: { 128 x: 0, 129 y: 10, 130 width: '100%', 131 height: '90%' 132 }, 133 maskColor: "#33AA0000" 134 } as promptAction.CustomDialogOptions; 135 136 Button("openCustomDialog maskOpt") 137 .width('100%') 138 .margin({ top: 10 }) 139 .onClick(() => { 140 this.getUIContext().getPromptAction().openCustomDialog(this.maskOpt) 141 }) 142``` 143  144 145 146在levelMode为LevelMode.EMBEDDED下,展示不同immersiveMode对蒙层在导航栏和状态栏的延伸效果。 147```ts 148// xxx.ets 149 @State immersiveMode: ImmersiveMode = ImmersiveMode.DEFAULT; 150 151 Button("openCustomDialog immersiveMode") 152 .width('100%') 153 .margin({ top: 10 }) 154 .onClick(() => { 155 this.immersiveMode = 156 this.immersiveMode == ImmersiveMode.DEFAULT ? ImmersiveMode.EXTEND : ImmersiveMode.DEFAULT; 157 this.getUIContext().getPromptAction().openCustomDialog({ 158 builder: () => { 159 this.myBuilder(); 160 }, 161 levelMode: LevelMode.EMBEDDED, 162 immersiveMode: this.immersiveMode, 163 }) 164 }) 165``` 166  167 168## 弹出框蒙层动画控制 169 170该示例通过transition和maskTransition分别展示弹出框在蒙层动画方面的能力。 171 172设置transition,实现弹出框与蒙层整体的动画。 173```ts 174// xxx.ets 175 transitionOpt: promptAction.CustomDialogOptions = { 176 builder: () => { 177 this.myBuilder(); 178 }, 179 transition: TransitionEffect.OPACITY.animation({ duration: 3000 }) 180 } as promptAction.CustomDialogOptions; 181 182 Button("openCustomDialog transition") 183 .width('100%') 184 .margin({ top: 10 }) 185 .onClick(() => { 186 this.getUIContext().getPromptAction().openCustomDialog(this.transitionOpt); 187 }) 188``` 189  190 191设置maskTransition,实现弹出框中蒙层单独的动画定制能力。 192```ts 193// xxx.ets 194 Button("openCustomDialog maskTransition") 195 .width('100%') 196 .margin({ top: 10 }) 197 .onClick(() => { 198 this.getUIContext().getPromptAction().openCustomDialog({ 199 builder: () => { 200 this.myBuilder(); 201 }, 202 maskTransition: TransitionEffect.OPACITY.animation({ duration: 2000 }) 203 .combine(TransitionEffect.rotate({ z: 1, angle: 180 })), 204 }); 205 }) 206``` 207  208 209[CustomDialog](arkts-common-components-custom-dialog.md)虽然不支持transition接口,但与之对应的openAnimation和closeAnimation接口在动画的打开和关闭时可进行定制,示例代码如下: 210 211```ts 212// xxx.ets 213 214@CustomDialog 215@Component 216struct CustomDialogExample { 217 controller?: CustomDialogController; 218 219 build() { 220 Column() { 221 Text("title") 222 .margin(10) 223 .fontSize(20) 224 Button("button1") 225 .margin(10) 226 .fontSize(20) 227 .onClick(() => { 228 this.controller?.close(); 229 }) 230 Button("button2") 231 .margin(10) 232 .fontSize(20) 233 .onClick(() => { 234 this.controller?.close(); 235 }) 236 }.width('100%') 237 .height('50%') 238 } 239} 240 241@Entry 242@Component 243struct Index { 244 animationController: CustomDialogController | null 245 = new CustomDialogController({ 246 builder: CustomDialogExample(), 247 closeAnimation: { duration: 2000 }, 248 openAnimation: { duration: 2000 } 249 }); 250 251 aboutToDisappear(): void { 252 this.animationController = null; 253 } 254 255 build() { 256 Column() { 257 Button("CustomDialogController animate") 258 .width('100%') 259 .margin({ top: 10 }) 260 .onClick(() => { 261 this.animationController?.open(); 262 }) 263 } 264 } 265} 266``` 267  268 269 270## 完整示例 271 272```ts 273// xxx.ets 274import { ImmersiveMode, LevelMode, promptAction } from '@kit.ArkUI'; 275 276@Entry 277@Component 278struct Index { 279 @State immersiveMode: ImmersiveMode = ImmersiveMode.DEFAULT; 280 autoCancelOpt: promptAction.CustomDialogOptions = { 281 builder: () => { 282 this.myBuilder(); 283 }, 284 autoCancel: false, 285 } as promptAction.CustomDialogOptions; 286 modalOpt: promptAction.CustomDialogOptions = { 287 builder: () => { 288 this.myBuilder(); 289 }, 290 isModal: false, 291 } as promptAction.CustomDialogOptions; 292 maskOpt: promptAction.CustomDialogOptions = { 293 builder: () => { 294 this.myBuilder(); 295 }, 296 maskRect: { 297 x: 0, 298 y: 10, 299 width: '100%', 300 height: '90%' 301 }, 302 maskColor: "#33AA0000" 303 } as promptAction.CustomDialogOptions; 304 transitionOpt: promptAction.CustomDialogOptions = { 305 builder: () => { 306 this.myBuilder(); 307 }, 308 transition: TransitionEffect.OPACITY.animation({ duration: 3000 }) 309 } as promptAction.CustomDialogOptions; 310 311 @Builder 312 myBuilder() { 313 Column() { 314 Text("title").margin(10).fontSize(20) 315 Button("button1").margin(10).fontSize(20) 316 Button("button2").margin(10).fontSize(20) 317 }.width('100%').height('50%') 318 } 319 320 build() { 321 Column() { 322 Button("openCustomDialog autoCancel:false") 323 .width('100%') 324 .margin({ top: 10 }) 325 .onClick(() => { 326 this.getUIContext().getPromptAction().openCustomDialog(this.autoCancelOpt) 327 }) 328 Button("openCustomDialog isModal:false") 329 .width('100%') 330 .margin({ top: 10 }) 331 .onClick(() => { 332 this.getUIContext().getPromptAction().openCustomDialog(this.modalOpt) 333 }) 334 Button("openCustomDialog maskOpt") 335 .width('100%') 336 .margin({ top: 10 }) 337 .onClick(() => { 338 this.getUIContext().getPromptAction().openCustomDialog(this.maskOpt) 339 }) 340 Button("openCustomDialog transition") 341 .width('100%') 342 .margin({ top: 10 }) 343 .onClick(() => { 344 this.getUIContext().getPromptAction().openCustomDialog(this.transitionOpt); 345 }) 346 Button("openCustomDialog immersiveMode") 347 .width('100%') 348 .margin({ top: 10 }) 349 .onClick(() => { 350 this.immersiveMode = 351 this.immersiveMode == ImmersiveMode.DEFAULT ? ImmersiveMode.EXTEND : ImmersiveMode.DEFAULT; 352 this.getUIContext().getPromptAction().openCustomDialog({ 353 builder: () => { 354 this.myBuilder(); 355 }, 356 levelMode: LevelMode.EMBEDDED, 357 immersiveMode: this.immersiveMode, 358 }) 359 }) 360 Button("openCustomDialog maskTransition") 361 .width('100%') 362 .margin({ top: 10 }) 363 .onClick(() => { 364 this.getUIContext().getPromptAction().openCustomDialog({ 365 builder: () => { 366 this.myBuilder(); 367 }, 368 maskTransition: TransitionEffect.OPACITY.animation({ duration: 2000 }) 369 .combine(TransitionEffect.rotate({ z: 1, angle: 180 })), 370 }); 371 }) 372 } 373 .width('100%') 374 .height('100%') 375 } 376} 377``` 378  379