1# 绑定全模态页面(bindContentCover) 2<!--Kit: ArkUI--> 3<!--Subsystem: ArkUI--> 4<!--Owner: @CCFFWW--> 5<!--Designer: @yangfan229--> 6<!--Tester: @lxl007--> 7<!--Adviser: @HelloCrease--> 8 9[全模态页面(bindContentCover)](../reference/apis-arkui/arkui-ts/ts-universal-attributes-modal-transition.md#bindcontentcover)是全屏模态形式的弹窗交互页面,完全覆盖底层父视图。适用于查看大图,全屏查看文稿等场景。 10 11## 使用约束 12 13全模态页面本质上是弹窗类组件,其交互层级默认为应用内顶层。 14 15[Navigation](../reference/apis-arkui/arkui-ts/ts-basic-components-navigation.md)导航转场时,新push的页面层级无法超出全模态,其效果仍然显示在模态页面之下。针对此类场景,建议将模态页面的内容迁移至转场页面中实现。例如,在上述情况下,可以使用NavDestination来替代拉起的模态页面,新push的页面层级低于全模态。 16 17## 生命周期 18 19全模态页面提供了生命周期函数,用于通知应用程序该弹窗的生命周期状态。生命周期的触发顺序依次为:onWillAppear -> onAppear -> onWillDisappear -> onDisappear。 20 21| 名称 |类型| 说明 | 22| ----------------- | ------ | ---------------------------- | 23| onWillAppear | () => void | 全模态页面显示(动画开始前)回调函数。 | 24| onAppear | () => void | 全模态页面显示(动画结束后)回调函数。 | 25| onWillDisappear | () => void | 全模态页面回退(动画开始前)回调函数。 | 26| onDisappear |() => void | 全模态页面回退(动画结束后)回调函数。 | 27 28## 使用bindContentCover构建全屏模态内容覆盖半模态 29 30全模态与半模态之间存在弹窗式的层级交互。后拉起的模态页面能够覆盖先前的模态页面。若开发者期望实现全屏转场,以覆盖半模态,并在全屏页面侧滑退出后,半模态页面仍保持显示,使用bindSheet结合bindContentCover将满足这一场景诉求。 31 32详见[模态转场](arkts-modal-transition.md#使用bindcontentcover构建全屏模态转场效果)章节,了解使用bindContentCover构建全屏模态转场效果。 33 34```ts 35import { curves } from '@kit.ArkUI'; 36 37interface PersonList { 38 name: string, 39 cardNum: string 40} 41 42@Entry 43@Component 44struct BindContentCoverDemo { 45 private personList: Array<PersonList> = [ 46 { name: '王**', cardNum: '1234***********789' }, 47 { name: '宋*', cardNum: '2345***********789' }, 48 { name: '许**', cardNum: '3456***********789' }, 49 { name: '唐*', cardNum: '4567***********789' } 50 ]; 51 // 半模态转场控制变量 52 @State isSheetShow: boolean = false; 53 // 全模态转场控制变量 54 @State isPresent: boolean = false; 55 56 @Builder 57 MyContentCoverBuilder() { 58 Column() { 59 Row() { 60 Text('选择乘车人') 61 .fontSize(20) 62 .fontColor(Color.White) 63 .width('100%') 64 .textAlign(TextAlign.Center) 65 .padding({ top: 30, bottom: 15 }) 66 } 67 .backgroundColor(0x007dfe) 68 69 Row() { 70 Text('+ 添加乘车人') 71 .fontSize(16) 72 .fontColor(0x333333) 73 .margin({ top: 10 }) 74 .padding({ top: 20, bottom: 20 }) 75 .width('92%') 76 .borderRadius(10) 77 .textAlign(TextAlign.Center) 78 .backgroundColor(Color.White) 79 } 80 81 Column() { 82 ForEach(this.personList, (item: PersonList, index: number) => { 83 Row() { 84 Column() { 85 if (index % 2 == 0) { 86 Column() 87 .width(20) 88 .height(20) 89 .border({ width: 1, color: 0x007dfe }) 90 .backgroundColor(0x007dfe) 91 } else { 92 Column() 93 .width(20) 94 .height(20) 95 .border({ width: 1, color: 0x007dfe }) 96 } 97 } 98 .width('20%') 99 100 Column() { 101 Text(item.name) 102 .fontColor(0x333333) 103 .fontSize(18) 104 Text(item.cardNum) 105 .fontColor(0x666666) 106 .fontSize(14) 107 } 108 .width('60%') 109 .alignItems(HorizontalAlign.Start) 110 111 Column() { 112 Text('编辑') 113 .fontColor(0x007dfe) 114 .fontSize(16) 115 } 116 .width('20%') 117 } 118 .padding({ top: 10, bottom: 10 }) 119 .border({ width: { bottom: 1 }, color: 0xf1f1f1 }) 120 .width('92%') 121 .backgroundColor(Color.White) 122 }) 123 } 124 .padding({ top: 20, bottom: 20 }) 125 126 Text('确认') 127 .width('90%') 128 .height(40) 129 .textAlign(TextAlign.Center) 130 .borderRadius(10) 131 .fontColor(Color.White) 132 .backgroundColor(0x007dfe) 133 .onClick(() => { 134 this.isPresent = !this.isPresent; 135 }) 136 } 137 .size({ width: '100%', height: '100%' }) 138 .backgroundColor(0xf5f5f5) 139 } 140 141 @Builder 142 TripInfo() { 143 Row() { 144 Column() { 145 Text('00:25') 146 Text('始发站') 147 } 148 .width('25%') 149 150 Column() { 151 Text('G1234') 152 Text('8时1分') 153 } 154 .width('25%') 155 156 Column() { 157 Text('08:26') 158 Text('终点站') 159 } 160 .width('25%') 161 } 162 } 163 164 // 第二步:定义半模态展示界面 165 // 通过@Builder构建模态展示界面 166 @Builder 167 MySheetBuilder() { 168 Column() { 169 Column() { 170 this.TripInfo() 171 } 172 .width('92%') 173 .margin(15) 174 .backgroundColor(Color.White) 175 .shadow({ radius: 30, color: '#aaaaaa' }) 176 .borderRadius(10) 177 178 Column() { 179 Text('+ 选择乘车人') 180 .fontSize(18) 181 .fontColor(Color.Orange) 182 .fontWeight(FontWeight.Bold) 183 .padding({ top: 10, bottom: 10 }) 184 .width('60%') 185 .textAlign(TextAlign.Center) 186 .borderRadius(15) 187 .onClick(() => { 188 // 第三步:通过全模态接口调起全模态展示界面,新拉起的模态面板默认显示在最上层 189 this.isPresent = !this.isPresent; 190 }) 191 // 通过全模态接口,绑定模态展示界面MyContentCoverBuilder。transition属性支持自定义转场效果,此处定义了x轴横向入场 192 .bindContentCover($$this.isPresent, this.MyContentCoverBuilder(), { 193 transition: TransitionEffect.translate({ x: 500 }).animation({ curve: curves.springMotion(0.6, 0.8) }) 194 }) 195 } 196 .padding({ top: 60 }) 197 } 198 } 199 200 build() { 201 Column() { 202 Row() { 203 this.TripInfo() 204 Text('有票') 205 .fontColor(Color.Blue) 206 .width('25%') 207 } 208 .width('100%') 209 .margin({top: 200, bottom: 30}) 210 .borderRadius(10) 211 .backgroundColor(Color.White) 212 .onClick(()=>{ 213 this.isSheetShow = !this.isSheetShow; 214 }) 215 // 第一步:定义半模态转场效果 216 .bindSheet($$this.isSheetShow, this.MySheetBuilder(), { 217 height: SheetSize.MEDIUM, 218 title: {title: "确认订单"}, 219 }) 220 } 221 .width('100%') 222 .height('100%') 223 .backgroundColor('#30aaaaaa') 224 } 225} 226``` 227 228