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