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```