1# Custom Dialog Box (CustomDialog) 2 3A custom dialog box is a dialog box you customize by using APIs of the **CustomDialogController** class. You can set the style and content to your preference for a custom dialog box. 4 5> **NOTE** 6> 7> The APIs of this module are supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 8 9 10## APIs 11 12constructor(value: CustomDialogControllerOptions) 13 14Defines a custom dialog box. 15 16> **NOTE** 17> 18> No parameters of the custom dialog box can be dynamically updated. 19 20**Atomic service API**: This API can be used in atomic services since API version 11. 21 22**System capability**: SystemCapability.ArkUI.ArkUI.Full 23 24**Parameters** 25 26| Name| Type | Mandatory| Description | 27| ------ | ------------------------------------------------------------ | ---- | ---------------------- | 28| value | [CustomDialogControllerOptions](#customdialogcontrolleroptions) | Yes | Parameters of the custom dialog box.| 29 30## CustomDialogControllerOptions 31 32**System capability**: SystemCapability.ArkUI.ArkUI.Full 33 34| Name | Type | Mandatory | Description | 35| ----------------------------- | ---------------------------------------- | ---- | ---------------------------------------- | 36| builder | [CustomDialog](../../../ui/arkts-common-components-custom-dialog.md) | Yes | Builder of the custom dialog box content.<br>**NOTE**<br>If the builder uses a callback as the input parameter, as in **build: custombuilder({ callback: ()=> {...}})**, pay attention to the binding of **this**.<br>To listen for data changes in the builder, use the @Link decorator; other decorators, such as @Prop and @ObjectLink, do not apply.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 37| cancel | () => void | No | Callback invoked when the dialog box is closed after the Back button or mask is touched or the Esc key is pressed.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 38| autoCancel | boolean | No | Whether to close the dialog box when the mask is touched. The value **true** means to close the dialog box when the mask is touched, and **false** means the opposite.<br>Default value: **true**<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 39| alignment | [DialogAlignment](ts-methods-alert-dialog-box.md#dialogalignment) | No | Alignment mode of the dialog box in the vertical direction.<br>Default value: **DialogAlignment.Default**<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 40| offset | [Offset](ts-types.md#offset) | No | Offset of the dialog box relative to the alignment position.<br>Default value: **{dx: 0, dy: 0}**<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 41| customStyle | boolean | No | Whether to use a custom style for the dialog box.<br>When this parameter is set to **false** (default value):<br>1. The rounded corner radius is 32 vp.<br>2. If the width and height of the dialog box are not set, the dialog box automatically adapts its width to the grid system and its height to the child components.<br>3. The set width of the dialog box cannot exceed the maximum width in the default style (100% width for a custom node), and the set height cannot exceed the maximum height (100% height for a custom node).<br>When this parameter is set to **true**:<br>1. The corner radius is 0, and the background color is transparent.<br>2. The width, height, border width, border style, border color, and shadow width cannot be set for the dialog box.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 42| gridCount<sup>8+</sup> | number | No | Number of [grid columns](../../../ui/arkts-layout-development-grid-layout.md) occupied by the dialog box.<br>The default value is subject to the window size, and the maximum value is the maximum number of columns supported by the system. If this parameter is set to an invalid value, the default value is used.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 43| maskColor<sup>10+</sup> | [ResourceColor](ts-types.md#resourcecolor) | No | Custom mask color.<br>Default value: **0x33000000**<br>**Atomic service API**: This API can be used in atomic services since API version 11. | 44| maskRect<sup>10+</sup> | [Rectangle](ts-methods-alert-dialog-box.md#rectangle8) | No | Mask area of the dialog box. Events outside the mask area are transparently transmitted, and events within the mask area are not.<br>Default value: **{ x: 0, y: 0, width: '100%', height: '100%' }**<br>**NOTE**<br>**maskRect** does not take effect when **showInSubWindow** is set to **true**.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 45| openAnimation<sup>10+</sup> | [AnimateParam](ts-explicit-animation.md#animateparam) | No | Parameters for defining the open animation of the dialog box.<br>**NOTE**<br>**tempo**: The default value is **1**; a value less than or equal to 0 is handled as the default value.<br>**iterations**: The default value is **1**, indicating that the animation is played once; any other value is handled as the default value.<br>**playMode**: The default value is **PlayMode.Normal**; any other value is handled as the default value.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 46| closeAnimation<sup>10+</sup> | [AnimateParam](ts-explicit-animation.md#animateparam) | No | Parameters for defining the close animation of the dialog box.<br>**NOTE**<br>**tempo**: The default value is **1**; a value less than or equal to 0 is handled as the default value.<br>**iterations**: The default value is **1**, indicating that the animation is played once; any other value is handled as the default value.<br>**playMode**: The default value is **PlayMode.Normal**; any other value is handled as the default value.<br>For page transition, you are advised to use the default close animation.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 47| showInSubWindow<sup>10+</sup> | boolean | No | Whether to show the dialog box in a sub-window when the dialog box needs to be displayed outside the main window.<br>Default value: **false**<br>**NOTE**<br>A dialog box whose **showInSubWindow** attribute is **true** cannot trigger the display of another dialog box whose **showInSubWindow** attribute is also **true**. Avoid using the **CalendarPicker**, **CalendarPickerDialog**, **DatePickerDialog**, **TextPickerDialog**, and **TimePickerDialog** components in the dialog box where **showInSubWindow** is set to **true**, as the dialog box may affect the behavior of these components.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 48| backgroundColor<sup>10+</sup> | [ResourceColor](ts-types.md#resourcecolor) | No | Background color of the dialog box.<br>Default value: **Color.Transparent**<br>**NOTE**<br>If the content builder also has the background color set, the background color set here will be overridden by the background color of the content builder.<br>When **backgroundColor** is set to a non-transparent color, **backgroundBlurStyle** must be set to **BlurStyle.NONE**; otherwise, the color display may not meet the expected effect.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 49| cornerRadius<sup>10+</sup> | [Dimension](ts-types.md#dimension10) \| [BorderRadiuses](ts-types.md#borderradiuses9) | No | Radius of the rounded corners of the background.<br>You can set separate radiuses for the four rounded corners.<br>Default value: **{ topLeft: '32vp', topRight: '32vp', bottomLeft: '32vp', bottomRight: '32vp' }**<br>**NOTE**<br>This attribute must be used together with the [borderRadius](ts-universal-attributes-border.md#borderradius) attribute.<br>**Atomic service API**: This API can be used in atomic services since API version 11.| 50| isModal<sup>11+</sup> | boolean | No| Whether the dialog box is a modal. A modal dialog box has a mask applied, while a non-modal dialog box does not.<br>Default value: **true**<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 51| onWillDismiss<sup>12+</sup> | Callback<[DismissDialogAction](#dismissdialogaction12)> | No| Callback for interactive closure of the dialog box.<br>**NOTE**<br>1. If this callback is registered, the dialog box will not be closed immediately after the user touches the mask or the Back button, presses the Esc key, or swipes left or right on the screen. The **reason** parameter in the callback is used to determine whether the dialog box can be closed. The reason returned by the component does not support the value **CLOSE_BUTTON**.<br>2. In the **onWillDismiss** callback, another **onWillDismiss** callback is not allowed.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 52| borderWidth<sup>12+</sup> | [Dimension](ts-types.md#dimension10) \| [EdgeWidths](ts-types.md#edgewidths9) | No| Border width of the dialog box.<br>You can set the width for all four sides or set separate widths for individual sides.<br>Default value: **0**<br> When set to a percentage, the value defines the border width as a percentage of the parent dialog box's width.<br>If the left and right borders are greater than its width, or the top and bottom borders are greater than its height, the dialog box may not display as expected.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 53| borderColor<sup>12+</sup> | [ResourceColor](ts-types.md#resourcecolor) \| [EdgeColors](ts-types.md#edgecolors9) | No| Border color of the dialog box.<br>Default value: **Color.Black**<br>**borderColor** must be used with **borderWidth** in pairs.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 54| borderStyle<sup>12+</sup> | [BorderStyle](ts-appendix-enums.md#borderstyle) \| [EdgeStyles](ts-types.md#edgestyles9) | No| Border style of the dialog box.<br>Default value: **BorderStyle.Solid**<br>**borderStyle** must be used with **borderWidth** in pairs.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 55| width<sup>12+</sup> | [Dimension](ts-types.md#dimension10) | No | Width of the dialog box.<br>**NOTE**<br>- Default maximum width of the dialog box: 400 vp<br>- When this parameter is set to a percentage, the reference width of the dialog box is the width of the window where the dialog box is located. You can decrease or increase the width as needed.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 56| height<sup>12+</sup> | [Dimension](ts-types.md#dimension10) | No| Height of the dialog box.<br>**NOTE**<br>- Default maximum height of the dialog box: 0.9 x (Window height – Safe area)<br>- When this parameter is set to a percentage, the reference height of the dialog box is the height of the window where the dialog box is located minus the safe area. You can decrease or increase the height as needed.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 57| shadow<sup>12+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions) \| [ShadowStyle](ts-universal-attributes-image-effect.md#shadowstyle10) | No| Shadow of the dialog box.<br> Default value on 2-in-1 devices: **ShadowStyle.OUTER_FLOATING_MD** when the dialog box is focused and **ShadowStyle.OUTER_FLOATING_SM** otherwise<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 58| backgroundBlurStyle<sup>12+</sup> | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | No | Background blur style of the dialog box.<br>Default value: **BlurStyle.COMPONENT_ULTRA_THICK**<br>**NOTE**<br>Setting this parameter to **BlurStyle.NONE** disables the background blur. When **backgroundBlurStyle** is set to a value other than **NONE**, do not set **backgroundColor**. If you do, the color display may not produce the expected visual effect.<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 59| keyboardAvoidMode<sup>12+</sup> | [KeyboardAvoidMode](../js-apis-promptAction.md#keyboardavoidmode12) | No| How the dialog box avoids the soft keyboard when it is brought up.<br>Default value: **KeyboardAvoidMode.DEFAULT**<br>**Atomic service API**: This API can be used in atomic services since API version 12.| 60| enableHoverMode<sup>13+</sup> | boolean | No | Whether to enable the hover state.<br>Default value: **false**, meaning not to enable the hover state.| 61| hoverModeArea<sup>13+</sup> | [HoverModeAreaType](ts-appendix-enums.md#hovermodeareatype13) | No | Display area of the dialog box in the hover state.<br>Default value: **HoverModeAreaType.BOTTOM_SCREEN**| 62 63> **NOTE** 64> 65> - Pressing the Back or ESC key closes the dialog box. 66> - If the dialog box reaches its maximum allowable height on the screen when avoiding the soft keyboard, it reduces its height to fit. 67> It should be noted that this height adjustment is applied to the outermost container. If a child component within this container has been assigned a larger fixed height, since the container does not clip its content by default, parts of the dialog box may still be displayed off-screen. 68> - Use the custom dialog box to contain simple alert messages only. Do not use it as a page. When the dialog box avoids the soft keyboard, there is a 16 vp safe spacing between the two. 69> 70> - Currently, ArkUI dialog boxes do not close automatically when you switch pages unless you manually call **close**. If you need a dialog box to close in sync with page navigation, consider using the **Navigation** component. For details, see the [page display mode: dialog mode](../../../ui/arkts-navigation-navigation.md#page-display-mode). 71 72## DismissDialogAction<sup>12+</sup> 73 74Provides information about the action to dismiss the dialog box. 75 76**Atomic service API**: This API can be used in atomic services since API version 12. 77 78**System capability**: SystemCapability.ArkUI.ArkUI.Full 79 80### Properties 81 82| Name | Type | Readable| Writable| Description | 83| ------- | ------------------------------------------------------------ | ---- | ---- | ------------------------------------------------------------ | 84| dismiss | Callback<void> | No | No | Callback for dismissing the dialog box. This API is called only when the dialog box needs to be exited.| 85| reason | [DismissReason](../js-apis-promptAction.md#dismissreason12) | No | No | Reason why the dialog box cannot be dismissed. You must specify whether to close the dialog box for each of the listed actions.| 86 87## CustomDialogController 88 89**Atomic service API**: This API can be used in atomic services since API version 11. 90 91### Objects to Import 92 93```ts 94dialogController : CustomDialogController | null = new CustomDialogController(CustomDialogControllerOptions) 95``` 96> **NOTE** 97> 98> **CustomDialogController** is effective only when it is a member variable of the **@CustomDialog** and **@Component** decorated struct and is defined in the **@Component** decorated struct. For details, see the following example. 99 100### open 101open() 102 103Opens the content of the custom dialog box. This API can be called multiple times. If the dialog box is displayed in a subwindow, no new subwindow is allowed. 104 105**Atomic service API**: This API can be used in atomic services since API version 11. 106 107**System capability**: SystemCapability.ArkUI.ArkUI.Full 108 109 110### close 111close() 112 113**Atomic service API**: This API can be used in atomic services since API version 11. 114 115**System capability**: SystemCapability.ArkUI.ArkUI.Full 116 117 118Closes the custom dialog box. If the dialog box is closed, this API does not take effect. 119 120## Example 121 122### Example 1 123 124```ts 125// xxx.ets 126@CustomDialog 127struct CustomDialogExampleTwo { 128 controllerTwo?: CustomDialogController 129 build() { 130 Column() { 131 Text('I'm the second dialog box') 132 .fontSize(30) 133 .height(100) 134 Button('Close Second Dialog Box') 135 .onClick(() => { 136 if (this.controllerTwo != undefined) { 137 this.controllerTwo.close() 138 } 139 }) 140 .margin(20) 141 } 142 } 143} 144@CustomDialog 145@Component 146struct CustomDialogExample { 147 @Link textValue: string 148 @Link inputValue: string 149 dialogControllerTwo: CustomDialogController | null = new CustomDialogController({ 150 builder: CustomDialogExampleTwo(), 151 alignment: DialogAlignment.Bottom, 152 onWillDismiss:(dismissDialogAction: DismissDialogAction)=> { 153 console.info("reason=" + JSON.stringify(dismissDialogAction.reason)) 154 console.log("dialog onWillDismiss") 155 if (dismissDialogAction.reason == DismissReason.PRESS_BACK) { 156 dismissDialogAction.dismiss() 157 } 158 if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) { 159 dismissDialogAction.dismiss() 160 } 161 }, 162 offset: { dx: 0, dy: -25 } }) 163 controller?: CustomDialogController 164 // You can pass in multiple other controllers in the CustomDialog to open one or more other CustomDialogs in the CustomDialog. In this case, you must place the controller pointing to the self behind all controllers. 165 cancel: () => void = () => { 166 } 167 confirm: () => void = () => { 168 } 169 170 build() { 171 Column() { 172 Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 }) 173 TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%') 174 .onChange((value: string) => { 175 this.textValue = value 176 }) 177 Text('Are you sure you want to change the text?').fontSize(16).margin({ bottom: 10 }) 178 Flex({ justifyContent: FlexAlign.SpaceAround }) { 179 Button('No') 180 .onClick(() => { 181 if (this.controller != undefined) { 182 this.controller.close() 183 this.cancel() 184 } 185 }).backgroundColor(0xffffff).fontColor(Color.Black) 186 Button('OK') 187 .onClick(() => { 188 if (this.controller != undefined) { 189 this.inputValue = this.textValue 190 this.controller.close() 191 this.confirm() 192 } 193 }).backgroundColor(0xffffff).fontColor(Color.Red) 194 }.margin({ bottom: 10 }) 195 196 Button('Open Second Dialog Box') 197 .onClick(() => { 198 if (this.dialogControllerTwo != null) { 199 this.dialogControllerTwo.open() 200 } 201 }) 202 .margin(20) 203 }.borderRadius(10) 204 // When using the border or cornerRadius attribute, use it together with the borderRadius attribute. 205 } 206} 207@Entry 208@Component 209struct CustomDialogUser { 210 @State textValue: string = '' 211 @State inputValue: string = 'click me' 212 dialogController: CustomDialogController | null = new CustomDialogController({ 213 builder: CustomDialogExample({ 214 cancel: ()=> { this.onCancel() }, 215 confirm: ()=> { this.onAccept() }, 216 textValue: $textValue, 217 inputValue: $inputValue 218 }), 219 cancel: this.exitApp, 220 autoCancel: true, 221 onWillDismiss:(dismissDialogAction: DismissDialogAction)=> { 222 console.info("reason=" + JSON.stringify(dismissDialogAction.reason)) 223 console.log("dialog onWillDismiss") 224 if (dismissDialogAction.reason == DismissReason.PRESS_BACK) { 225 dismissDialogAction.dismiss() 226 } 227 if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) { 228 dismissDialogAction.dismiss() 229 } 230 }, 231 alignment: DialogAlignment.Bottom, 232 offset: { dx: 0, dy: -20 }, 233 gridCount: 4, 234 customStyle: false, 235 cornerRadius: 10, 236 }) 237 238 // Set dialogController to null when the custom component is about to be destroyed. 239 aboutToDisappear() { 240 this.dialogController = null // Set dialogController to null. 241 } 242 243 onCancel() { 244 console.info('Callback when the first button is clicked') 245 } 246 247 onAccept() { 248 console.info('Callback when the second button is clicked') 249 } 250 251 exitApp() { 252 console.info('Click the callback in the blank area') 253 } 254 build() { 255 Column() { 256 Button(this.inputValue) 257 .onClick(() => { 258 if (this.dialogController != null) { 259 this.dialogController.open() 260 } 261 }).backgroundColor(0x317aff) 262 }.width('100%').margin({ top: 5 }) 263 } 264} 265``` 266 267 268 269### Example 2 270 271```ts 272// xxx.ets 273@CustomDialog 274struct CustomDialogExample { 275 controller?: CustomDialogController 276 cancel: () => void = () => { 277 } 278 confirm: () => void = () => { 279 } 280 build() { 281 Column() { 282 Text('Dialog box outside the main window') 283 .fontSize(30) 284 .height(100) 285 Button('Close') 286 .onClick(() => { 287 if (this.controller != undefined) { 288 this.controller.close() 289 } 290 }) 291 .margin(20) 292 } 293 } 294} 295@Entry 296@Component 297struct CustomDialogUser { 298 dialogController: CustomDialogController | null = new CustomDialogController({ 299 builder: CustomDialogExample({ 300 cancel: ()=> { this.onCancel() }, 301 confirm: ()=> { this.onAccept() } 302 }), 303 cancel: this.existApp, 304 autoCancel: true, 305 onWillDismiss:(dismissDialogAction: DismissDialogAction)=> { 306 console.info("reason=" + JSON.stringify(dismissDialogAction.reason)) 307 console.log("dialog onWillDismiss") 308 if (dismissDialogAction.reason == DismissReason.PRESS_BACK) { 309 dismissDialogAction.dismiss() 310 } 311 if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) { 312 dismissDialogAction.dismiss() 313 } 314 }, 315 alignment: DialogAlignment.Center, 316 offset: { dx: 0, dy: -20 }, 317 gridCount: 4, 318 showInSubWindow: true, 319 isModal: true, 320 customStyle: false, 321 cornerRadius: 10, 322 }) 323 // Set dialogController to null when the custom component is about to be destroyed. 324 aboutToDisappear() { 325 this.dialogController = null // Set dialogController to null. 326 } 327 328 onCancel() { 329 console.info('Callback when the first button is clicked') 330 } 331 332 onAccept() { 333 console.info('Callback when the second button is clicked') 334 } 335 336 existApp() { 337 console.info('Click the callback in the blank area') 338 } 339 340 build() { 341 Column() { 342 Button('Click Me') 343 .onClick(() => { 344 if (this.dialogController != null) { 345 this.dialogController.open() 346 } 347 }).backgroundColor(0x317aff) 348 }.width('100%').margin({ top: 5 }) 349 } 350} 351``` 352 353 354 355### Example 3 356This example demonstrates how to set styles of a custom dialog box, including the width, height, background color, and shadow. 357```ts 358// xxx.ets 359@CustomDialog 360struct CustomDialogExample { 361 controller?: CustomDialogController 362 cancel: () => void = () => { 363 } 364 confirm: () => void = () => { 365 } 366 build() { 367 Column() { 368 Text('This is a custom dialog box') 369 .fontSize(30) 370 .height(100) 371 Button('Close') 372 .onClick(() => { 373 if (this.controller != undefined) { 374 this.controller.close() 375 } 376 }) 377 .margin(20) 378 } 379 } 380} 381@Entry 382@Component 383struct CustomDialogUser { 384 dialogController: CustomDialogController | null = new CustomDialogController({ 385 builder: CustomDialogExample({ 386 cancel: ()=> { this.onCancel() }, 387 confirm: ()=> { this.onAccept() } 388 }), 389 cancel: this.existApp, 390 autoCancel: true, 391 onWillDismiss:(dismissDialogAction: DismissDialogAction)=> { 392 console.info("reason=" + JSON.stringify(dismissDialogAction.reason)) 393 console.log("dialog onWillDismiss") 394 if (dismissDialogAction.reason == DismissReason.PRESS_BACK) { 395 dismissDialogAction.dismiss() 396 } 397 if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) { 398 dismissDialogAction.dismiss() 399 } 400 }, 401 alignment: DialogAlignment.Center, 402 offset: { dx: 0, dy: -20 }, 403 customStyle: false, 404 cornerRadius: 20, 405 width: 300, 406 height: 200, 407 borderWidth: 1, 408 borderStyle: BorderStyle.Dashed,// borderStyle must be used with borderWidth in pairs. 409 borderColor: Color.Blue,// borderColor must be used with borderWidth in pairs. 410 backgroundColor: Color.White, 411 shadow: ({ radius: 20, color: Color.Grey, offsetX: 50, offsetY: 0}), 412 }) 413 // Set dialogController to null when the custom component is about to be destroyed. 414 aboutToDisappear() { 415 this.dialogController = null // Set dialogController to null. 416 } 417 418 onCancel() { 419 console.info('Callback when the first button is clicked') 420 } 421 422 onAccept() { 423 console.info('Callback when the second button is clicked') 424 } 425 426 existApp() { 427 console.info('Click the callback in the blank area') 428 } 429 430 build() { 431 Column() { 432 Button('Click Me') 433 .onClick(() => { 434 if (this.dialogController != null) { 435 this.dialogController.open() 436 } 437 }).backgroundColor(0x317aff) 438 }.width('100%').margin({ top: 5 }) 439 } 440} 441``` 442 443 444 445### Example 4 446 447This example demonstrates how to set the layout area of a dialog box in the hover state on a foldable device. 448 449```ts 450@CustomDialog 451@Component 452struct CustomDialogExample { 453 @Link textValue: string; 454 @Link inputValue: string; 455 controller?: CustomDialogController; 456 457 build() { 458 Column() { 459 Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 }) 460 TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%') 461 .onChange((value: string) => { 462 this.textValue = value; 463 }) 464 Text('Are you sure you want to change the text?').fontSize(16).margin({ bottom: 10 }) 465 Flex({ justifyContent: FlexAlign.SpaceAround }) { 466 Button('No') 467 .onClick(() => { 468 if (this.controller != undefined) { 469 this.controller.close(); 470 } 471 }).backgroundColor(0xffffff).fontColor(Color.Black) 472 Button('OK') 473 .onClick(() => { 474 if (this.controller != undefined) { 475 this.inputValue = this.textValue; 476 this.controller.close(); 477 } 478 }).backgroundColor(0xffffff).fontColor(Color.Red) 479 }.margin({ bottom: 10 }) 480 481 Button('Open Second Dialog Box') 482 .margin(20) 483 }.borderRadius(10) 484 // When using the border or cornerRadius attribute, use it together with the borderRadius attribute. 485 } 486} 487@Entry 488@Component 489struct CustomDialogUser { 490 @State textValue: string = ''; 491 @State inputValue: string = 'click me'; 492 dialogController: CustomDialogController | null = new CustomDialogController({ 493 builder: CustomDialogExample({ 494 textValue: $textValue, 495 inputValue: $inputValue 496 }), 497 cancel: this.exitApp, 498 autoCancel: true, 499 onWillDismiss: (dismissDialogAction: DismissDialogAction)=> { 500 console.info("reason=" + JSON.stringify(dismissDialogAction.reason)); 501 console.log("dialog onWillDismiss"); 502 if (dismissDialogAction.reason == DismissReason.PRESS_BACK) { 503 dismissDialogAction.dismiss(); 504 } 505 if (dismissDialogAction.reason == DismissReason.TOUCH_OUTSIDE) { 506 dismissDialogAction.dismiss(); 507 } 508 }, 509 alignment: DialogAlignment.Bottom, 510 offset: { dx: 0, dy: -20 }, 511 gridCount: 4, 512 customStyle: false, 513 cornerRadius: 10, 514 enableHoverMode: true, 515 hoverModeArea: HoverModeAreaType.TOP_SCREEN 516 }) 517 518 // Set dialogController to null when the custom component is about to be destroyed. 519 aboutToDisappear() { 520 this.dialogController = null; // Set dialogController to null. 521 } 522 523 exitApp() { 524 console.info('Click the callback in the blank area'); 525 } 526 527 build() { 528 Column() { 529 Button(this.inputValue) 530 .onClick(() => { 531 if (this.dialogController != null) { 532 this.dialogController.open(); 533 } 534 }).backgroundColor(0x317aff) 535 }.width('100%').margin({ top: 5 }) 536 } 537} 538``` 539 540 541