1# 全屏模态转场 2 3通过bindContentCover属性为组件绑定全屏模态页面,在组件插入和删除时可通过设置转场参数ModalTransition显示过渡动效。 4 5> **说明:** 6> 7> 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8> 9> 不支持横竖屏切换。 10> 11> 不支持路由跳转。 12 13## bindContentCover 14 15bindContentCover(isShow: Optional\<boolean\>, builder: CustomBuilder, options?: ContentCoverOptions) 16 17给组件绑定全屏模态页面,点击后显示模态页面。模态页面内容自定义,显示方式可设置无动画过渡,上下切换过渡以及透明渐变过渡方式。 18 19**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 20 21**系统能力:** SystemCapability.ArkUI.ArkUI.Full 22 23**参数:** 24 25| 参数名 | 类型 | 必填 | 说明 | 26| ------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | 27| isShow | Optional\<boolean\> | 是 | 是否显示全屏模态页面。<br/>从API version 10开始,该参数支持[$$](../../../quick-start/arkts-two-way-sync.md)双向绑定变量。| 28| builder | [CustomBuilder](ts-types.md#custombuilder8) | 是 | 配置全屏模态页面内容。 | 29| options | [ContentCoverOptions](#contentcoveroptions) | 否 | 配置全屏模态页面的可选属性。 | 30 31## ContentCoverOptions 32继承自[BindOptions](ts-universal-attributes-sheet-transition.md#bindoptions)。 33| 名称 | 类型 | 必填 | 描述 | 34| --------------- | ---------------------------------------- | ---- | ------------- | 35| modalTransition | [ModalTransition](ts-types.md#modaltransition10) | 否 | 全屏模态页面的转场方式。<br />**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | 36| onWillDismiss<sup>12+</sup> | Callback<[DismissContentCoverAction](#dismisscontentcoveraction12类型说明)> | 否 | 全屏模态页面交互式关闭回调函数。<br/>**说明:**<br />当用户执行back事件关闭交互操作时,如果注册该回调函数,则不会立刻关闭。在回调函数中可以通过reason得到阻拦关闭页面的操作类型,从而根据原因选择是否关闭全屏模态页面。在onWillDismiss回调中,不能再做onWillDismiss拦截。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 37| transition<sup>12+</sup> | [TransitionEffect](ts-transition-animation-component.md#transitioneffect10对象说明) | 否 | 全屏模态页面的转场方式。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| 38 39## DismissContentCoverAction<sup>12+</sup>类型说明 40 41**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 42 43| 名称 | 类型 | 必填 | 描述 | 44| --------------- | ---------------------------------------- | ---- | ------------- | 45| dismiss | function | 是 | 全屏模态页面关闭回调函数。开发者需要退出页面时调用。 | 46| reason | [DismissReason](ts-universal-attributes-popup.md#dismissreason12枚举说明) | 是 | 返回本次拦截全屏模态页面退出的事件原因。 | 47 48## 示例 49 50### 示例1(使用全屏模态转场) 51 52该示例主要演示通过bindContentCover来实现全屏模态转场。 53 54```ts 55// xxx.ets 56@Entry 57@Component 58struct ModalTransitionExample { 59 @State isShow: boolean = false 60 @State isShow2: boolean = false 61 62 @Builder 63 myBuilder2() { 64 Column() { 65 Button("close modal 2") 66 .margin(10) 67 .fontSize(20) 68 .onClick(() => { 69 this.isShow2 = false; 70 }) 71 } 72 .width('100%') 73 .height('100%') 74 } 75 76 @Builder 77 myBuilder() { 78 Column() { 79 Button("transition modal 2") 80 .margin(10) 81 .fontSize(20) 82 .onClick(() => { 83 this.isShow2 = true; 84 }).bindContentCover(this.isShow2, this.myBuilder2(), { 85 modalTransition: ModalTransition.NONE, 86 backgroundColor: Color.Orange, 87 onWillAppear: () => { 88 console.log("BindContentCover onWillAppear.") 89 }, 90 onAppear: () => { 91 console.log("BindContentCover onAppear.") 92 }, 93 onWillDisappear: () => { 94 console.log("BindContentCover onWillDisappear.") 95 }, 96 onDisappear: () => { 97 console.log("BindContentCover onDisappear.") 98 } 99 }) 100 101 Button("close modal 1") 102 .margin(10) 103 .fontSize(20) 104 .onClick(() => { 105 this.isShow = false; 106 }) 107 } 108 .width('100%') 109 .height('100%') 110 .justifyContent(FlexAlign.Center) 111 } 112 113 build() { 114 Column() { 115 Button("transition modal 1") 116 .onClick(() => { 117 this.isShow = true 118 }) 119 .fontSize(20) 120 .margin(10) 121 .bindContentCover(this.isShow, this.myBuilder(), { 122 modalTransition: ModalTransition.NONE, 123 backgroundColor: Color.Pink, 124 onWillAppear: () => { 125 console.log("BindContentCover onWillAppear.") 126 }, 127 onAppear: () => { 128 console.log("BindContentCover onAppear.") 129 }, 130 onWillDisappear: () => { 131 console.log("BindContentCover onWillDisappear.") 132 }, 133 onDisappear: () => { 134 console.log("BindContentCover onDisappear.") 135 } 136 }) 137 } 138 .justifyContent(FlexAlign.Center) 139 .backgroundColor("#ff49c8ab") 140 .width('100%') 141 .height('100%') 142 } 143} 144``` 145 146 147 148### 示例2(自定义转场动画) 149 150全屏模态无动画转场模式下,自定义转场动画。 151 152```ts 153// xxx.ets 154import { curves } from '@kit.ArkUI'; 155 156@Entry 157@Component 158struct ModalTransitionExample { 159 @State @Watch("isShow1Change") isShow: boolean = false 160 @State @Watch("isShow2Change") isShow2: boolean = false 161 @State isScale1: number = 1; 162 @State isScale2: number = 1; 163 164 isShow1Change() { 165 this.isShow ? this.isScale1 = 0.95 : this.isScale1 = 1 166 } 167 168 isShow2Change() { 169 this.isShow2 ? this.isScale2 = 0.95 : this.isScale2 = 1 170 } 171 172 @Builder 173 myBuilder2() { 174 Column() { 175 Button("close modal 2") 176 .margin(10) 177 .fontSize(20) 178 .onClick(() => { 179 this.isShow2 = false; 180 }) 181 } 182 .width('100%') 183 .height('100%') 184 } 185 186 @Builder 187 myBuilder() { 188 Column() { 189 Button("transition modal 2") 190 .margin(10) 191 .fontSize(20) 192 .onClick(() => { 193 this.isShow2 = true; 194 }).bindContentCover(this.isShow2, this.myBuilder2(), { 195 modalTransition: ModalTransition.NONE, 196 backgroundColor: Color.Orange, 197 onWillAppear: () => { 198 console.log("BindContentCover onWillAppear.") 199 }, 200 onAppear: () => { 201 console.log("BindContentCover onAppear.") 202 }, 203 onWillDisappear: () => { 204 console.log("BindContentCover onWillDisappear.") 205 }, 206 onDisappear: () => { 207 console.log("BindContentCover onDisappear.") 208 } 209 }) 210 211 Button("close modal 1") 212 .margin(10) 213 .fontSize(20) 214 .onClick(() => { 215 this.isShow = false; 216 }) 217 } 218 .width('100%') 219 .height('100%') 220 .justifyContent(FlexAlign.Center) 221 .scale({ x: this.isScale2, y: this.isScale2 }) 222 .animation({ curve: curves.springMotion() }) 223 } 224 225 build() { 226 Column() { 227 Button("transition modal 1") 228 .onClick(() => { 229 this.isShow = true 230 }) 231 .fontSize(20) 232 .margin(10) 233 .bindContentCover(this.isShow, this.myBuilder(), { 234 modalTransition: ModalTransition.NONE, 235 backgroundColor: Color.Pink, 236 onWillAppear: () => { 237 console.log("BindContentCover onWillAppear.") 238 }, 239 onAppear: () => { 240 console.log("BindContentCover onAppear.") 241 }, 242 onWillDisappear: () => { 243 console.log("BindContentCover onWillDisappear.") 244 }, 245 onDisappear: () => { 246 console.log("BindContentCover onDisappear.") 247 } 248 }) 249 } 250 .justifyContent(FlexAlign.Center) 251 .backgroundColor("#ff49c8ab") 252 .width('100%') 253 .height('100%') 254 .scale({ x: this.isScale1, y: this.isScale1 }) 255 .animation({ curve: curves.springMotion() }) 256 } 257} 258``` 259 260 261 262### 示例3(上下切换转场) 263 264全屏模态上下切换转场。 265 266```ts 267// xxx.ets 268@Entry 269@Component 270struct ModalTransitionExample { 271 @State isShow: boolean = false 272 @State isShow2: boolean = false 273 274 @Builder 275 myBuilder2() { 276 Column() { 277 Button("close modal 2") 278 .margin(10) 279 .fontSize(20) 280 .onClick(() => { 281 this.isShow2 = false; 282 }) 283 } 284 .width('100%') 285 .height('100%') 286 } 287 288 @Builder 289 myBuilder() { 290 Column() { 291 Button("transition modal 2") 292 .margin(10) 293 .fontSize(20) 294 .onClick(() => { 295 this.isShow2 = true; 296 }).bindContentCover(this.isShow2, this.myBuilder2(), { 297 modalTransition: ModalTransition.DEFAULT, 298 backgroundColor: Color.Gray, 299 onWillAppear: () => { 300 console.log("BindContentCover onWillAppear.") 301 }, 302 onAppear: () => { 303 console.log("BindContentCover onAppear.") 304 }, 305 onWillDisappear: () => { 306 console.log("BindContentCover onWillDisappear.") 307 }, 308 onDisappear: () => { 309 console.log("BindContentCover onDisappear.") 310 } 311 }) 312 313 Button("close modal 1") 314 .margin(10) 315 .fontSize(20) 316 .onClick(() => { 317 this.isShow = false; 318 }) 319 } 320 .width('100%') 321 .height('100%') 322 .justifyContent(FlexAlign.Center) 323 } 324 325 build() { 326 Column() { 327 Button("transition modal 1") 328 .onClick(() => { 329 this.isShow = true 330 }) 331 .fontSize(20) 332 .margin(10) 333 .bindContentCover(this.isShow, this.myBuilder(), { 334 modalTransition: ModalTransition.DEFAULT, 335 backgroundColor: Color.Pink, 336 onWillAppear: () => { 337 console.log("BindContentCover onWillAppear.") 338 }, 339 onAppear: () => { 340 console.log("BindContentCover onAppear.") 341 }, 342 onWillDisappear: () => { 343 console.log("BindContentCover onWillDisappear.") 344 }, 345 onDisappear: () => { 346 console.log("BindContentCover onDisappear.") 347 } 348 }) 349 } 350 .justifyContent(FlexAlign.Center) 351 .backgroundColor(Color.White) 352 .width('100%') 353 .height('100%') 354 } 355} 356``` 357 358 359 360### 示例4(透明度渐变转场) 361 362全屏模态透明度渐变转场。 363 364```ts 365// xxx.ets 366@Entry 367@Component 368struct ModalTransitionExample { 369 @State isShow: boolean = false 370 @State isShow2: boolean = false 371 372 @Builder 373 myBuilder2() { 374 Column() { 375 Button("close modal 2") 376 .margin(10) 377 .fontSize(20) 378 .onClick(() => { 379 this.isShow2 = false; 380 }) 381 } 382 .width('100%') 383 .height('100%') 384 .justifyContent(FlexAlign.Center) 385 } 386 387 @Builder 388 myBuilder() { 389 Column() { 390 Button("transition modal 2") 391 .margin(10) 392 .fontSize(20) 393 .onClick(() => { 394 this.isShow2 = true; 395 }).bindContentCover(this.isShow2, this.myBuilder2(), { 396 modalTransition: ModalTransition.ALPHA, 397 backgroundColor: Color.Gray, 398 onWillAppear: () => { 399 console.log("BindContentCover onWillAppear.") 400 }, 401 onAppear: () => { 402 console.log("BindContentCover onAppear.") 403 }, 404 onWillDisappear: () => { 405 console.log("BindContentCover onWillDisappear.") 406 }, 407 onDisappear: () => { 408 console.log("BindContentCover onDisappear.") 409 } 410 }) 411 412 Button("close modal 1") 413 .margin(10) 414 .fontSize(20) 415 .onClick(() => { 416 this.isShow = false; 417 }) 418 } 419 .width('100%') 420 .height('100%') 421 .justifyContent(FlexAlign.Center) 422 } 423 424 build() { 425 Column() { 426 Button("transition modal 1") 427 .onClick(() => { 428 this.isShow = true 429 }) 430 .fontSize(20) 431 .margin(10) 432 .bindContentCover(this.isShow, this.myBuilder(), { 433 modalTransition: ModalTransition.ALPHA, 434 backgroundColor: Color.Pink, 435 onWillAppear: () => { 436 console.log("BindContentCover onWillAppear.") 437 }, 438 onAppear: () => { 439 console.log("BindContentCover onAppear.") 440 }, 441 onWillDisappear: () => { 442 console.log("BindContentCover onWillDisappear.") 443 }, 444 onDisappear: () => { 445 console.log("BindContentCover onDisappear.") 446 } 447 }) 448 } 449 .justifyContent(FlexAlign.Center) 450 .backgroundColor(Color.White) 451 .width('100%') 452 .height('100%') 453 } 454} 455``` 456 457 458 459### 示例5(设置不同效果的自定义转场) 460 461该示例主要演示全屏模态旋转,平移等自定义转场。 462 463```ts 464// xxx.ets 465@Entry 466@Component 467struct ModalTransitionExample { 468 @State isShow: boolean = false 469 @State isShow2: boolean = false 470 471 @Builder 472 myBuilder2() { 473 Column() { 474 Button("Close Modal 2") 475 .margin(10) 476 .fontSize(20) 477 .onClick(() => { 478 this.isShow2 = false; 479 }) 480 } 481 .width('100%') 482 .height('100%') 483 .justifyContent(FlexAlign.Center) 484 } 485 486 @Builder 487 myBuilder() { 488 Column() { 489 Button("Transition Modal 2") 490 .margin(10) 491 .fontSize(20) 492 .onClick(() => { 493 this.isShow2 = true; 494 }) 495 .bindContentCover( 496 this.isShow2, 497 this.myBuilder2(), 498 { 499 modalTransition: ModalTransition.DEFAULT, 500 backgroundColor: Color.Gray, 501 transition: TransitionEffect.SLIDE.animation({ duration: 5000, curve: Curve.LinearOutSlowIn }), 502 onWillDismiss: ((dismissContentCoverAction: DismissContentCoverAction) => { 503 if (dismissContentCoverAction.reason == DismissReason.PRESS_BACK) { 504 console.log("BindContentCover dismiss reason is back pressed") 505 } 506 dismissContentCoverAction.dismiss() 507 }), 508 onAppear: () => { 509 console.info("BindContentCover onAppear.") 510 }, 511 onDisappear: () => { 512 this.isShow2 = false; 513 console.info("BindContentCover onDisappear.") 514 } 515 }) 516 517 Button("Close Modal 1") 518 .margin(10) 519 .fontSize(20) 520 .onClick(() => { 521 this.isShow = false; 522 }) 523 } 524 .width('100%') 525 .height('100%') 526 .justifyContent(FlexAlign.Center) 527 } 528 529 build() { 530 Column() { 531 Button("Transition Modal 1") 532 .onClick(() => { 533 this.isShow = true 534 }) 535 .fontSize(20) 536 .margin(10) 537 .bindContentCover( 538 this.isShow, 539 this.myBuilder(), 540 { 541 modalTransition: ModalTransition.DEFAULT, 542 backgroundColor: Color.Pink, 543 transition: TransitionEffect.asymmetric( 544 TransitionEffect.OPACITY.animation({ duration: 1100 }).combine( 545 TransitionEffect.rotate({ z: 1, angle: 180 }).animation({ delay: 1000, duration: 1000 })) 546 , 547 TransitionEffect.OPACITY.animation({ duration: 1200 }).combine( 548 TransitionEffect.rotate({ z: 1, angle: 180 }).animation({ duration: 1300 })) 549 ), 550 onWillDismiss: ((dismissContentCoverAction: DismissContentCoverAction) => { 551 if (dismissContentCoverAction.reason == DismissReason.PRESS_BACK) { 552 console.log("back pressed"); 553 } 554 dismissContentCoverAction.dismiss() 555 }), 556 onAppear: () => { 557 console.log("BindContentCover onAppear.") 558 }, 559 onDisappear: () => { 560 this.isShow = false; 561 console.log("BindContentCover onDisappear.") 562 } 563 }) 564 } 565 .justifyContent(FlexAlign.Center) 566 .backgroundColor(Color.White) 567 .width('100%') 568 .height('100%') 569 } 570} 571``` 572 573 574