• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ![dialog_mask_autoCancel](figures/dialog_mask_autoCancel.gif)
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 ![dialog_mask_modal](figures/dialog_mask_modal.PNG)
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 ![dialog_mask_mask](figures/dialog_mask_mask.PNG)
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 ![dialog_mask_immersiveMode](figures/dialog_mask_immersiveMode.gif)
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 ![dialog_mask_transition](figures/dialog_mask_transition.gif)
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 ![dialog_mask_maskTransition](figures/dialog_mask_maskTransition.gif)
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 ![CustomDialogController](figures/dialog_mask_CustomDialogController.gif)
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 ![openCustomDialog](figures/dialog_mask_openCustomDialog.gif)
379