1# 自定义弹窗 2 3通过CustomDialogController类显示自定义弹窗。使用弹窗组件时,可优先考虑自定义弹窗,便于自定义弹窗的样式与内容。 4 5> **说明:** 6> 7> 从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9 10## 接口 11 12CustomDialogController(value:{builder: CustomDialog, cancel?: () => void, autoCancel?: boolean, alignment?: DialogAlignment, offset?: Offset, customStyle?: boolean, gridCount?: number, maskColor?: ResourceColor, maskRect?: Rectangle, openAnimation?: AnimateParam, closeAniamtion?: AnimateParam, showInSubWindow?: boolean, backgroundColor?:ResourceColor, cornerRadius?:Dimension \| BorderRadiuses}) 13 14**参数:** 15 16| 参数名 | 参数类型 | 必填 | 参数描述 | 17| ----------------------------- | ---------------------------------------- | ---- | ---------------------------------------- | 18| builder | CustomDialog | 是 | 自定义弹窗内容构造器。 | 19| cancel | () => void | 否 | 点击遮障层退出时的回调。 | 20| autoCancel | boolean | 否 | 是否允许点击遮障层退出。<br>默认值:true | 21| alignment | [DialogAlignment](ts-methods-alert-dialog-box.md#dialogalignment枚举说明) | 否 | 弹窗在竖直方向上的对齐方式。<br>默认值:DialogAlignment.Default | 22| offset | [Offset](ts-types.md#offset) | 否 | 弹窗相对alignment所在位置的偏移量。 | 23| customStyle | boolean | 否 | 弹窗容器样式是否自定义。<br>默认值:false,弹窗容器的宽度根据栅格系统自适应,不跟随子节点;高度自适应子节点,最大为窗口高度的90%;圆角为24vp。 | 24| gridCount<sup>8+</sup> | number | 否 | 弹窗宽度占[栅格宽度](../../ui/arkts-layout-development-grid-layout.md)的个数。<br>默认为按照窗口大小自适应,异常值按默认值处理,最大栅格数为系统最大栅格数。 | 25| maskColor<sup>10+</sup> | [ResourceColor](ts-types.md#resourcecolor) | 否 | 自定义蒙层颜色。<br>默认值: 0x33000000 | 26| maskRect<sup>10+</sup> | [Rectangle](ts-methods-alert-dialog-box.md#rectangle10类型说明) | 否 | 弹窗遮蔽层区域,在遮蔽层区域内的事件不透传,在遮蔽层区域外的事件透传。<br/>默认值:{ x: 0, y: 0, width: '100%', height: '100%' } | 27| openAnimation<sup>10+</sup> | [AnimateParam](ts-explicit-animation.md#animateparam对象说明) | 否 | 自定义设置弹窗弹出的动画效果相关参数。<br>**说明**:<br>iterations默认值为1,默认播放一次,设置为其他数值时按默认值处理。<br>playMode控制动画播放模式,默认值为PlayMode.Normal,设置为其他数值时按照默认值处理。 | 28| closeAniamtion<sup>10+</sup> | [AnimateParam](ts-explicit-animation.md#animateparam对象说明) | 否 | 自定义设置弹窗关闭的动画效果相关参数。<br>**说明**:<br>iterations默认值为1,默认播放一次,设置为其他数值时按默认值处理。<br>playMode控制动画播放模式,默认值为PlayMode.Normal,设置为其他数值时按照默认值处理。 | 29| showInSubWindow<sup>10+</sup> | boolean | 否 | 是否在子窗口显示弹窗。<br>默认值:false,在子窗口不显示弹窗。<br>**说明**:showInSubWindow为true的弹窗无法触发显示另一个showInSubWindow为true的弹窗。 | 30| backgroundColor<sup>10+</sup> | [ResourceColor](ts-types.md#resourcecolor) | 否 | 设置弹窗背板填充。br />**说明**:如果同时设置了内容构造器的背景色,则backgroundColor会被内容构造器的背景色覆盖。 | | 31| cornerRadius<sup>10+</sup> | [BorderRadiuses](ts-types.md#borderradiuses9) \| [Dimension](ts-types.md#dimension10) | 否 | 设置背板的圆角半径。<br />可分别设置4个圆角的半径。<br />默认值:{ topLeft: '24vp', topRight: '24vp', bottomLeft: '24vp', bottomRight: '24vp' }<br />**说明**:自定义弹窗默认的背板圆角半径为24vp,如果需要使用cornerRadius属性,请和[borderRadius](ts-universal-attributes-border.md)属性一起使用。 | 32 33## CustomDialogController 34 35### 导入对象 36 37``` 38let dialogController : CustomDialogController = new CustomDialogController(...) 39``` 40**说明**:CustomDialogController仅在作为@CustomDialog和@Component struct的成员变量,且在@Component struct内部定义时赋值才有效,具体用法可看下方示例。 41 42### open() 43open(): void 44 45 46显示自定义弹窗内容,允许多次使用,但如果弹框为SubWindow模式,则该弹框不允许再弹出SubWindow弹框。 47 48 49### close 50close(): void 51 52 53关闭显示的自定义弹窗,若已关闭,则不生效。 54 55 56## 示例 57 58```ts 59// xxx.ets 60@CustomDialog 61struct CustomDialogExampleTwo { 62 controllerTwo?: CustomDialogController 63 64 build() { 65 Column() { 66 Text('我是第二个弹窗') 67 .fontSize(30) 68 .height(100) 69 Button('点我关闭第二个弹窗') 70 .onClick(() => { 71 if (this.controllerTwo != undefined) { 72 this.controllerTwo.close() 73 } 74 }) 75 .margin(20) 76 } 77 } 78} 79 80@CustomDialog 81struct CustomDialogExample { 82 @Link textValue: string 83 @Link inputValue: string 84 dialogControllerTwo: CustomDialogController | null = new CustomDialogController({ 85 builder: CustomDialogExampleTwo(), 86 alignment: DialogAlignment.Bottom, 87 offset: { dx: 0, dy: -25 } }) 88 controller?: CustomDialogController 89 // 若尝试在CustomDialog中传入多个其他的Controller,以实现在CustomDialog中打开另一个或另一些CustomDialog,那么此处需要将指向自己的controller放在所有controller的后面 90 cancel: () => void = () => { 91 } 92 confirm: () => void = () => { 93 } 94 95 build() { 96 Column() { 97 Text('Change text').fontSize(20).margin({ top: 10, bottom: 10 }) 98 TextInput({ placeholder: '', text: this.textValue }).height(60).width('90%') 99 .onChange((value: string) => { 100 this.textValue = value 101 }) 102 Text('Whether to change a text?').fontSize(16).margin({ bottom: 10 }) 103 Flex({ justifyContent: FlexAlign.SpaceAround }) { 104 Button('cancel') 105 .onClick(() => { 106 if (this.controller != undefined) { 107 this.controller.close() 108 this.cancel() 109 } 110 }).backgroundColor(0xffffff).fontColor(Color.Black) 111 Button('confirm') 112 .onClick(() => { 113 if (this.controller != undefined) { 114 this.inputValue = this.textValue 115 this.controller.close() 116 this.confirm() 117 } 118 }).backgroundColor(0xffffff).fontColor(Color.Red) 119 }.margin({ bottom: 10 }) 120 121 Button('点我打开第二个弹窗') 122 .onClick(() => { 123 if (this.dialogControllerTwo != null) { 124 this.dialogControllerTwo.open() 125 } 126 }) 127 .margin(20) 128 }.borderRadius(10) 129 // 如果需要使用border属性或cornerRadius属性,请和borderRadius属性一起使用。 130 } 131} 132 133@Entry 134@Component 135struct CustomDialogUser { 136 @State textValue: string = '' 137 @State inputValue: string = 'click me' 138 dialogController: CustomDialogController | null = new CustomDialogController({ 139 builder: CustomDialogExample({ 140 cancel: this.onCancel, 141 confirm: this.onAccept, 142 textValue: $textValue, 143 inputValue: $inputValue 144 }), 145 cancel: this.existApp, 146 autoCancel: true, 147 alignment: DialogAlignment.Bottom, 148 offset: { dx: 0, dy: -20 }, 149 gridCount: 4, 150 customStyle: false, 151 backgroundColor: 0xd9ffffff, 152 cornerRadius: 10, 153 }) 154 155 // 在自定义组件即将析构销毁时将dialogControlle置空 156 aboutToDisappear() { 157 this.dialogController = null // 将dialogController置空 158 } 159 160 onCancel() { 161 console.info('Callback when the first button is clicked') 162 } 163 164 onAccept() { 165 console.info('Callback when the second button is clicked') 166 } 167 168 existApp() { 169 console.info('Click the callback in the blank area') 170 } 171 172 build() { 173 Column() { 174 Button(this.inputValue) 175 .onClick(() => { 176 if (this.dialogController != null) { 177 this.dialogController.open() 178 } 179 }).backgroundColor(0x317aff) 180 }.width('100%').margin({ top: 5 }) 181 } 182} 183``` 184 185 186