跳到主要内容

绑定全模态页面(bindContentCover)

全模态页面(bindContentCover)是全屏模态形式的弹窗交互页面,完全覆盖底层父视图。适用于查看大图,全屏查看文稿等场景。

使用约束

全模态页面本质上是弹窗类组件,其交互层级默认为应用内顶层。

Navigation导航转场时,新push的页面层级无法超出全模态,其效果仍然显示在模态页面之下。针对此类场景,建议将模态页面的内容迁移至转场页面中实现。例如,在上述情况下,可以使用NavDestination来替代拉起的模态页面,新push的页面层级低于全模态。

生命周期

全模态页面提供了生命周期函数,用于通知应用程序该弹窗的生命周期状态。生命周期的触发顺序依次为:onWillAppear -> onAppear -> onWillDisappear -> onDisappear。

名称类型说明
onWillAppear() => void全模态页面显示(动画开始前)回调函数。
onAppear() => void全模态页面显示(动画结束后)回调函数。
onWillDisappear() => void全模态页面回退(动画开始前)回调函数。
onDisappear() => void全模态页面回退(动画结束后)回调函数。

使用bindContentCover构建全屏模态内容覆盖半模态

全模态与半模态之间存在弹窗式的层级交互。后拉起的模态页面能够覆盖先前的模态页面。若开发者期望实现全屏转场,以覆盖半模态,并在全屏页面侧滑退出后,半模态页面仍保持显示,使用bindSheet结合bindContentCover将满足这一场景诉求。

详见模态转场章节,了解使用bindContentCover构建全屏模态转场效果。

import { curves } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';

interface PersonList {
name: string,
cardNum: string
}

@Entry
@Component
struct BindContentCoverDemo {
private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
private manager = this.context.resourceManager;
private personList: Array<PersonList> = [
// 'Person_example1'资源文件中的value值为'王**'
{ name: this.manager.getStringByNameSync('Person_example1'), cardNum: '1234***********789' },
// 'Person_example2'资源文件中的value值为'宋*'
{ name: this.manager.getStringByNameSync('Person_example2'), cardNum: '2345***********789' },
// 'Person_example3'资源文件中的value值为'许**'
{ name: this.manager.getStringByNameSync('Person_example3'), cardNum: '3456***********789' },
// 'Person_example4'资源文件中的value值为'唐*'
{ name: this.manager.getStringByNameSync('Person_example4'), cardNum: '4567***********789' }
];
// 半模态转场控制变量
@State isSheetShow: boolean = false;
// 全模态转场控制变量
@State isPresent: boolean = false;

@Builder
MyContentCoverBuilder() {
Column() {
Row() {
// 请将$r('app.string.Text_choose_person')替换为实际资源文件,在本示例中该资源文件的value值为"选择乘车人"
Text($r('app.string.Text_choose_person'))
.fontSize(20)
.fontColor(Color.White)
.width('100%')
.textAlign(TextAlign.Center)
.padding({ top: 30, bottom: 15 })
}
.backgroundColor(0x007dfe)

Row() {
// 请将$r('app.string.Text_add_person')替换为实际资源文件,在本示例中该资源文件的value值为"+ 添加乘车人"
Text($r('app.string.Text_add_person'))
.fontSize(16)
.fontColor(0x333333)
.margin({ top: 10 })
.padding({ top: 20, bottom: 20 })
.width('92%')
.borderRadius(10)
.textAlign(TextAlign.Center)
.backgroundColor(Color.White)
}

Column() {
ForEach(this.personList, (item: PersonList, index: number) => {
Row() {
Column() {
if (index % 2 == 0) {
Column()
.width(20)
.height(20)
.border({ width: 1, color: 0x007dfe })
.backgroundColor(0x007dfe)
} else {
Column()
.width(20)
.height(20)
.border({ width: 1, color: 0x007dfe })
}
}
.width('20%')

Column() {
Text(item.name)
.fontColor(0x333333)
.fontSize(18)
Text(item.cardNum)
.fontColor(0x666666)
.fontSize(14)
}
.width('60%')
.alignItems(HorizontalAlign.Start)

Column() {
// 请将$r('app.string.Text_edit')替换为实际资源文件,在本示例中该资源文件的value值为"编辑"
Text($r('app.string.Text_edit'))
.fontColor(0x007dfe)
.fontSize(16)
}
.width('20%')
}
.padding({ top: 10, bottom: 10 })
.border({ width: { bottom: 1 }, color: 0xf1f1f1 })
.width('92%')
.backgroundColor(Color.White)
})
}
.padding({ top: 20, bottom: 20 })

// 请将$r('app.string.Text_confirm')替换为实际资源文件,在本示例中该资源文件的value值为"确认"
Text($r('app.string.Text_confirm'))
.width('90%')
.height(40)
.textAlign(TextAlign.Center)
.borderRadius(10)
.fontColor(Color.White)
.backgroundColor(0x007dfe)
.onClick(() => {
this.isPresent = !this.isPresent;
})
}
.size({ width: '100%', height: '100%' })
.backgroundColor(0xf5f5f5)
}

@Builder
TripInfo() {
Row() {
Column() {
Text('00:25')
// 请将$r('app.string.Label_origin_station')替换为实际资源文件,在本示例中该资源文件的value值为"始发站"
Text($r('app.string.Label_origin_station'))
}
.width('25%')

Column() {
Text('G1234')
// 请将$r('app.string.Label_start_time')替换为实际资源文件,在本示例中该资源文件的value值为"8时1分"
Text($r('app.string.Label_start_time'))
}
.width('25%')

Column() {
Text('08:26')
// 请将$r('app.string.Label_destination_station')替换为实际资源文件,在本示例中该资源文件的value值为"终点站"
Text($r('app.string.Label_destination_station'))
}
.width('25%')
}
}

// 第二步:定义半模态展示界面
// 通过@Builder构建模态展示界面
@Builder
MySheetBuilder() {
Column() {
Column() {
this.TripInfo()
}
.width('92%')
.margin(15)
.backgroundColor(Color.White)
.shadow({ radius: 30, color: '#aaaaaa' })
.borderRadius(10)

Column() {
// 请将$r('app.string.Sheet_choose_person')替换为实际资源文件,在本示例中该资源文件的value值为"+ 选择乘车人"
Text($r('app.string.Sheet_choose_person'))
.fontSize(18)
.fontColor(Color.Orange)
.fontWeight(FontWeight.Bold)
.padding({ top: 10, bottom: 10 })
.width('60%')
.textAlign(TextAlign.Center)
.borderRadius(15)
.onClick(() => {
// 第三步:通过全模态接口调起全模态展示界面,新拉起的模态面板默认显示在最上层
this.isPresent = !this.isPresent;
})
// 通过全模态接口,绑定模态展示界面MyContentCoverBuilder。transition属性支持自定义转场效果,此处定义了x轴横向入场
.bindContentCover($$this.isPresent, this.MyContentCoverBuilder(), {
transition: TransitionEffect.translate({ x: 500 }).animation({ curve: curves.springMotion(0.6, 0.8) })
})
}
.padding({ top: 60 })
}
}

build() {
Column() {
Row() {
this.TripInfo()
// 请将$r('app.string.Sheet_tickets_available')替换为实际资源文件,在本示例中该资源文件的value值为"有票"
Text($r('app.string.Sheet_tickets_available'))
.fontColor(Color.Blue)
.width('25%')
}
.width('100%')
.margin({top: 200, bottom: 30})
.borderRadius(10)
.backgroundColor(Color.White)
.onClick(()=>{
this.isSheetShow = !this.isSheetShow;
})
// 第一步:定义半模态转场效果
.bindSheet($$this.isSheetShow, this.MySheetBuilder(), {
height: SheetSize.MEDIUM,
// 请将$r('app.string.Text_confirm_order')替换为实际资源文件,在本示例中该资源文件的value值为"确认订单"
title: {title: $r('app.string.Text_confirm_order')},
})
}
.width('100%')
.height('100%')
.backgroundColor('#30aaaaaa')
}
}