1、概 述
在项目开发中,我们可能会遇到临时交互的场景(即:弹出一个临时交互框,交互完毕后继续用户的主流程),效果如下:
在ArkUI中,此类弹出窗被称为“半模态页面”,ArkUI为我们提供了一套可以快速实现此效果的接口,本文针对此效果的实现做讨论。
2、接口定义
给组件绑定半模态页面,点击后显示模态页面。接口定义如下:
bindSheet(isShow: Optional<boolean>, builder: CustomBuilder, options?: SheetOptions)
用法类似如下(第5行代码):
build() {
Column() {
Button("点击我弹出上拉抽屉")
// ... 其他属性
.bindSheet($$this.isShow, this.myBuilder(), {
// 三挡高度(默认是中间)
detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
blurStyle: BlurStyle.Thick,
showClose: true,
title: { title: "抽屉标题", subtitle: "抽屉副标题" },
})
}
.justifyContent(FlexAlign.Start)
.width('100%')
.height('100%')
}
其中:
isShow是可以支持双向绑定的显示/隐藏的切换控制;
builder是抽屉需要显示的内容,内容构造器;
options是配置参数,定义如下:
名称 |
类型 |
说明 |
backgroundColor |
ResourceColor |
半模态页面的背板颜色。默认值:Color.White。 |
onWillAppear |
() => void |
半模态页面显示(动画开始前)回调函数。 |
onAppear |
() => void |
半模态页面显示(动画结束后)回调函数。 |
onWillDisappear |
() => void |
半模态页面回退(动画开始前)回调函数。 |
onDisappear |
() => void |
半模态页面回退(动画结束后)回调函数。 |
height |
SheetSize | Length |
半模态高度,默认是LARGE。 |
detents |
[(SheetSize | Length), ( SheetSize | Length)?, (SheetSize | Length)?] |
半模态页面的切换高度档位。 |
preferType |
SheetType |
半模态页面的样式。 |
showClose |
boolean | Resource |
是否显示关闭图标,默认显示。 |
dragBar |
boolean |
是否显示控制条。 |
blurStyle |
BlurStyle |
半模态面板的模糊背景。默认无模糊背景。 |
maskColor |
ResourceColor |
半模态页面的背景蒙层颜色。 |
title |
SheetTitleOptions | CustomBuilder |
半模态面板的标题。 |
enableOutsideInteractive |
boolean |
半模态所在页面是否允许交互。 |
shouldDismiss |
(sheetDismiss: SheetDismiss) => void |
半模态页面交互式关闭回调函数。 |
onWillDismiss |
DismissSheetAction |
半模态页面交互式关闭回调函数。说明:当用户执行关闭操作时,如果注册该回调函数,不会立刻关闭, 由开发者控制是否关闭。在回调函数中可以通过reason得到关闭页面的操作类型,从而根据原因选择是否关闭半模态页面。在onWillDismiss回调中,不能再做onWillDismiss拦截。元服务API: 从API version 12开始,该接口支持在元服务中使用。 |
onWillSpringBackWhenDismiss |
SpringBackAction |
半模态页面交互式关闭前控制回弹函数。 |
onHeightDidChange |
Callback<number> |
半模态页面高度变化回调函数。 |
onDetentsDidChange |
Callback<number> |
半模态页面档位变化回调函数。 |
onWidthDidChange |
Callback<number> |
半模态页面宽度变化回调函数。 |
onTypeDidChange |
Callback<SheetType> |
半模态页面形态变化回调函数。 |
borderWidth |
Dimension | EdgeWidths | LocalizedEdgeWidths |
设置半模态页面的边框宽度。可分别设置4个边框宽度。默认值:0。百分比参数方式:以父元素半模态页面宽的百分比来设置半模态页面的边框宽度。当半模态页面左边框和右边框大于半模态页面宽度,半模态页面上边框和下边框大于半模态页面高度,显示可能不符合预期。说明:底部弹窗时,底部边框宽度设置无效。 |
borderColor |
ResourceColor | EdgeColors | LocalizedEdgeColors |
设置半模态页面的边框颜色。默认值:Color.Black。如果使用borderColor属性,需要和borderWidth属性一起使用。说明:底部弹窗时,底部边框颜色设置无效。 |
borderStyle |
BorderStyle | EdgeStyles |
设置半模态页面的边框样式。默认值:BorderStyle.Solid。如果使用borderStyle属性,需要和borderWidth属性一起使用。说明:底部弹窗时,底部边框样式设置无效。 |
width |
Dimension |
设置半模态页面的宽度。百分比参数方式:以父元素宽的百分比来设置半模态页面的宽度。 |
shadow |
ShadowOptions | ShadowStyle |
设置半模态页面的阴影。 |
uiContext |
UIContext |
在UIContext实例对应的窗口中显示半模态。说明:使用openBindSheet启动的半模态页面,不支持设置、更新该属性。元服务API: 从API version 12开始,该接口支持在元服务中使用。 |
mode |
SheetMode |
设置半模态页面的显示层级。默认值:SheetMode.OVERLAY。 |
scrollSizeMode |
ScrollSizeMode |
设置半模态面板滑动时,内容区域刷新时机。默认值:ScrollSizeMode.FOLLOW_DETENT 。 |
3、案 例
实现一个案例效果如下:
代码如下(24~30行的配置,5~15行的builder):
@Entry
@Component
struct SheetTransitionExample {
@State isShow: boolean = false
@Builder
myBuilder() {
Column() {
Text('欢迎加入【Harmony自习室】')
.fontSize(20)
Button("确认")
.margin(10)
.fontSize(20)
}
.width('100%')
}
build() {
Column() {
Button("点击我弹出上拉抽屉")
.onClick(() => {
this.isShow = true
})
.fontSize(20)
.margin(10)
.bindSheet($$this.isShow, this.myBuilder(), {
// 三挡高度(默认是中间)
detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
blurStyle: BlurStyle.Thick,
showClose: true,
title: { title: "抽屉标题", subtitle: "抽屉副标题" },
})
}
.justifyContent(FlexAlign.Start)
.width('100%')
.height('100%')
}
}