# 半模态转场 通过bindSheet属性为组件绑定半模态页面,在组件插入时可通过设置自定义或默认的内置高度确定半模态大小。 > **说明:** > > 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 > > 不支持路由跳转。 ## bindSheet bindSheet(isShow: Optional\, builder: CustomBuilder, options?: SheetOptions) 给组件绑定半模态页面,点击后显示模态页面。 **原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 **系统能力:** SystemCapability.ArkUI.ArkUI.Full **参数:** | 参数名 | 类型 | 必填 | 说明 | | ------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | | isShow | Optional\ | 是 | 是否显示半模态页面。
从API version 10开始,该参数支持[$$](../../../quick-start/arkts-two-way-sync.md)双向绑定变量。 | | builder | [CustomBuilder](ts-types.md#custombuilder8) | 是 | 配置半模态页面内容。 | | options | [SheetOptions](#sheetoptions) | 否 | 配置半模态页面的可选属性。 | > **说明:** > > 1. 在非双向绑定情况下,以拖拽方式关闭半模态页面不会改变isShow参数的值。 > > 2. 为了使isShow参数值与半模态界面的状态同步,建议使用[$$](../../../quick-start/arkts-two-way-sync.md)双向绑定isShow参数。 > > 3. 在半模态单挡位向上拖拽或是多挡位上滑换挡情况下,内容在拖拽结束或换挡结束后更新显示区域。 > > 4. 半模态是一个严格和宿主节点绑定在一起的弹窗。若是想实现类似“页面显示的瞬间就弹出半模态”的效果,请确认宿主节点是否已挂载上树。若宿主节点还没上树就将isShow置为true,半模态将不生效。建议使用[onAppear](ts-universal-events-show-hide.md#onappear)函数,确保在宿主节点挂载后再显示半模态。 > 尤其是 [SheetMode](#sheetmode12) = EMBEDDED 时,除宿主节点外,还需确保对应的页面节点成功挂载。 > > 5. 半模态页面的离场动效不支持打断,动效执行期间无法响应其他手势动作。目前离场动效使用[弹簧曲线](../../../ui/arkts-spring-curve.md),该动画曲线存在视觉上并不明显的拖尾动画。因此,在半模态退出时,视觉上半模态页面已经消失,但此时动效可能还未结束,若想再次点击拉起半模态页面则不会响应。需要等动效完全结束后,才可以再次拉起。 > ## SheetOptions 继承自[BindOptions](#bindoptions)。 | 名称 | 类型 | 必填 | 描述 | | --------------- | ---------------------------------------- | ---- | --------------- | | height | [SheetSize](#sheetsize枚举说明) \| [Length](ts-types.md#length) | 否 | 半模态高度,默认是LARGE。
**说明:**
API version 12之前,底部弹窗横屏时该属性设置无效,高度为距离屏幕顶部8vp。
API version 12开始,底部弹窗横屏时该属性设置生效,最大高度为距离屏幕顶部8vp。
API version 14开始,底部弹窗横屏时,无状态栏则最大高度为距离屏幕顶部8vp,有状态栏则最大高度为距离状态栏8vp。
底部弹窗时,当设置detents时,该属性设置无效。
底部弹窗竖屏时,最大高度为距离状态栏8vp。
居中弹窗和跟手弹窗设置类型为SheetSize.LARGE和SheetSize.MEDIUM无效,显示默认高度560vp。居中弹窗和跟手弹窗最小高度为320vp,最大高度为窗口短边的90%。当使用Length设置的高度和使用SheetSize.FIT_CONTENT自适应的高度大于最大高度,则显示最大高度,小于最小高度,则显示最小高度。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | | detents11+ | [([SheetSize](#sheetsize枚举说明) \| [Length](ts-types.md#length)), ( [SheetSize](#sheetsize枚举说明) \| [Length](ts-types.md#length))?, ([SheetSize](#sheetsize枚举说明) \| [Length](ts-types.md#length))?] | 否 | 半模态页面的切换高度档位。
**说明:**
从API version 12开始,底部弹窗横屏时该属性设置生效。
底部弹窗竖屏生效,元组中第一个高度为初始高度。
面板可跟手滑动切换档位,松手后是否滑动至目标档位有两个判断条件:速度和距离。速度超过阈值,则执行滑动至与手速方向一致的目标档位;速度小于阈值,则引入距离判断条件,当位移距离>当前位置与目标位置的1/2,滑动至与手速方向一致的目标档位,位移距离当前位置与目标位置的1/2,返回至当前档位。速度阈值:1000,距离阈值:50%。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | preferType11+ | [SheetType](#sheettype11枚举说明) | 否 | 半模态页面的样式。
**说明:**
半模态在不同窗口所支持的显示类型:
1. 宽度 < 600vp:底部。
2. 600vp <= 宽度 < 840vp:底部、居中。默认居中样式。
3. 宽度 >= 840vp:底部、居中、跟手。默认跟手样式。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | showClose11+ | boolean \| [Resource](ts-types.md#resource) | 否 | 是否显示关闭图标,默认显示。
2in1设备默认无按钮底板。
**说明:**
Resource需要为boolean类型。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | dragBar | boolean | 否 | 是否显示控制条。
**说明:**
半模态面板的detents属性设置多个不同高度并且设置生效时,默认显示控制条。否则不显示控制条。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | | blurStyle11+ | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | 否 | 半模态面板的模糊背景。默认无模糊背景。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | maskColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 半模态页面的背景蒙层颜色。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | | title11+ | [SheetTitleOptions](#sheettitleoptions11) \| [CustomBuilder](ts-types.md#custombuilder8) | 否 | 半模态面板的标题。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | enableOutsideInteractive11+ | boolean | 否 | 半模态所在页面是否允许交互。
**说明:**
设置为true时允许交互,不显示蒙层;设置为false时不允许交互,显示蒙层;若不进行设置,默认底部弹窗与居中弹窗不允许交互,跟手弹窗允许交互。当设置为true时,maskColor设置无效。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | shouldDismiss11+ | (sheetDismiss: [SheetDismiss](#sheetdismiss11)) => void | 否 | 半模态页面交互式关闭回调函数。
**说明:**
当用户执行下拉关闭、触发back事件、点击遮罩层关闭或关闭按钮的交互操作时,如果已注册回调函数,模态窗口将不会立即关闭。要关闭半模态,需在回调函数中调用shouldDismiss.dismiss()方法来实现。
如果不注册该回调函数,则用户执行下拉关闭、触发back事件、点击遮罩层关闭或关闭按钮的交互操作时,正常关闭半模态,无其他行为。
建议在[二次确认](../../../ui/arkts-sheet-page.md#二次确认能力)场景使用。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | onWillDismiss12+ | [DismissSheetAction](#dismisssheetaction12) | 否 | 半模态页面的交互式关闭回调函数允许开发者注册,以获取关闭操作的类型,并决定是否关闭半模态状态。
**说明:**
当用户触发关闭操作时,若已注册回调函数,则不会立即关闭页面,而是由开发者通过回调函数中的[reason](../js-apis-promptAction.md#dismissreason12枚举说明)参数判断关闭操作的类型,进而根据具体原因自主选择是否关闭半模态页面。
如果不注册该回调函数,则用户执行关闭操作时,正常关闭半模态,无其他行为。
在onWillDismiss回调中,不能再做onWillDismiss拦截。
建议在[二次确认](../../../ui/arkts-sheet-page.md#二次确认能力)场景使用。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | onWillSpringBackWhenDismiss12+ | [SpringBackAction](#springbackaction12) | 否 | 半模态页面交互式关闭前控制回弹函数允许开发者注册,以控制半模态页面交互式关闭时的回弹效果。
**说明:**
当用户触发执行下拉关闭操作并同时注册该回调函数与shouldDimiss或onWillDismiss时,由开发者控制下滑关闭时是否回弹。在回调函数中可以通过调用springBack来实现回弹效果。也可以通过不调用springBack来取消回弹效果。
若不注册该回调函数,但注册shouldDimiss或onWillDismiss时,则默认在下滑关闭时,会触发回弹效果,回弹后再根据shouldDimiss或onWillDismiss内的回调行为决定半模态是否关闭。
如果不注册该回调函数,且未注册shouldDimiss或onWillDismiss时,默认在下滑关闭时,触发半模态关闭。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | onHeightDidChange12+ | Callback<number> | 否 | 半模态页面高度变化回调函数。
**说明:**
底部弹窗时,只有档位变化和拖拽跟手才返回每一帧高度,拉起半模态和避让软键盘只返回最后的高度,其他弹窗只在半模态拉起返回最后高度。
返回值为px。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | onDetentsDidChange12+ | Callback<number> | 否 | 半模态页面档位变化回调函数。
**说明:**
底部弹窗时,档位变化返回最后的高度。
返回值为px。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | onWidthDidChange12+ | Callback<number> | 否 | 半模态页面宽度变化回调函数。
**说明:**
宽度变化时返回最后的宽度。
返回值为px。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | onTypeDidChange12+ | Callback<[SheetType](#sheettype11枚举说明)> | 否 | 半模态页面形态变化回调函数。
**说明:**
形态变化时返回最后的形态。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | borderWidth12+ | [Dimension](ts-types.md#dimension10) \| [EdgeWidths](ts-types.md#edgewidths9) \| [LocalizedEdgeWidths](ts-types.md#localizededgewidths12)12+ | 否 | 设置半模态页面的边框宽度。
可分别设置4个边框宽度。
默认值:0
百分比参数方式:以父元素半模态页面宽的百分比来设置半模态页面的边框宽度。
当半模态页面左边框和右边框大于半模态页面宽度,半模态页面上边框和下边框大于半模态页面高度,显示可能不符合预期。
**说明:**
底部弹窗时,底部边框宽度设置无效。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | borderColor12+ | [ResourceColor](ts-types.md#resourcecolor) \| [EdgeColors](ts-types.md#edgecolors9) \| [LocalizedEdgeColors](ts-types.md#localizededgecolors12)12+ | 否 | 设置半模态页面的边框颜色。
默认值:Color.Black
如果使用borderColor属性,需要和borderWidth属性一起使用。
**说明:**
底部弹窗时,底部边框颜色设置无效。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | borderStyle12+ | [BorderStyle](ts-appendix-enums.md#borderstyle) \| [EdgeStyles](ts-types.md#edgestyles9) | 否 | 设置半模态页面的边框样式。
默认值:BorderStyle.Solid
如果使用borderStyle属性,需要和borderWidth属性一起使用。
**说明:**
底部弹窗时,底部边框样式设置无效。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | width12+ | [Dimension](ts-types.md#dimension10) | 否 | 设置半模态页面的宽度。
百分比参数方式:以父元素宽的百分比来设置半模态页面的宽度。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | shadow12+ | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明) \| [ShadowStyle](ts-universal-attributes-image-effect.md#shadowstyle10枚举说明) | 否 | 设置半模态页面的阴影。
2in1设备默认值:ShadowStyle.OUTER_FLOATING_SM。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | uiContext12+ | [UIContext](../js-apis-arkui-UIContext.md#uicontext) | 否 | 在UIContext实例对应的窗口中显示半模态。
**说明:**
使用[openBindSheet](../js-apis-arkui-UIContext.md#openbindsheet12)启动的半模态页面,不支持设置、更新该属性。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。| | mode12+ | [SheetMode](#sheetmode12) | 否 | 设置半模态页面的显示层级。
默认值:SheetMode.OVERLAY
**说明:**
1. 半模态显示期间mode属性不支持动态切换,两种模式的显示层级完全不同,无法做到显示期间同一个半模态从一个层级变换到另一个层级。建议在使用时明确诉求固定mode值。
2. 设置SheetMode.EMBEDDED时不支持设置UIContext属性,两者对应的半模态显示层级效果互相冲突。
3. 使用[openBindSheet](../js-apis-arkui-UIContext.md#openbindsheet12)启动半模态页面,若未传入有效的targetId,则不支持设置为SheetMode.EMBEDDED,默认为SheetMode.OVERLAY。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | scrollSizeMode12+ | [ScrollSizeMode](#scrollsizemode12) | 否 | 设置半模态面板滑动时,内容区域刷新时机。
默认值:ScrollSizeMode.FOLLOW_DETENT | | keyboardAvoidMode13+ | [SheetKeyboardAvoidMode](#sheetkeyboardavoidmode13枚举说明) | 否 | 设置半模态激活输入法时对软键盘的避让方式。
**默认值:** TRANSLATE_AND_SCROLL
**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。 | | enableHoverMode14+ | boolean | 否 | 是否响应悬停态。
默认值:false,默认不响应。
**说明:**
底部弹窗样式和跟手弹窗样式不响应悬停态。| | hoverModeArea14+ | [HoverModeAreaType](ts-appendix-enums.md#hovermodeareatype14) | 否 | 悬停态下弹窗默认展示区域。
默认值:HoverModeAreaType.BOTTOM_SCREEN| ## SheetSize枚举说明 | 名称 | 值 | 参数描述 | | ------------------------- | ---- | -------------------------------- | | MEDIUM | 0 | 指定半模态高度为屏幕高度一半。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | | LARGE | 1 | 指定半模态高度几乎为屏幕高度。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | | FIT_CONTENT11+ | 2 | 指定半模态高度为适应内容的高度。
**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | ## BindOptions | 名称 | 类型 | 必填 | 说明 | | --------------- | ------------------------------------------ | ---- | ------------------------ | | backgroundColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 半模态页面的背板颜色。
默认值:Color.White。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | | onWillAppear12+ | () => void | 否 | 半模态页面显示(动画开始前)回调函数。**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | onAppear | () => void | 否 | 半模态页面显示(动画结束后)回调函数。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | | onWillDisappear12+ | () => void | 否 | 半模态页面回退(动画开始前)回调函数。
**说明:**
不允许在onWillDisappear函数中修改状态变量,可能会导致组件行为不稳定。**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | | onDisappear | () => void | 否 | 半模态页面回退(动画结束后)回调函数。
**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 | ## SheetType11+枚举说明 **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 名称 | 值 | 参数描述 | | ------ | ---- | ------------------------------------------------------ | | BOTTOM | 0 | 底部弹窗。 | | CENTER | 1 | 居中弹窗。 | | POPUP | 2 | 跟手弹窗。跟手弹窗面板不支持跟手滑动,下滑面板不关闭。 | ## SheetDismiss11+ **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 名称 | 类型 | 必填 | 描述 | | ------- | ---------- | ---- | ------------------------------------------------------------ | | dismiss | () => void | 是 | 半模态面板关闭回调函数。开发者需要退出时调用,不需要退出时无需调用。 | ## SheetTitleOptions11+ **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 名称 | 类型 | 必填 | 描述 | | -------- | -------------------------------------- | ---- | -------------------- | | title | [ResourceStr](ts-types.md#resourcestr) | 是 | 半模态面板的主标题。 | | subtitle | [ResourceStr](ts-types.md#resourcestr) | 否 | 半模态面板的副标题。 | ## SheetMode12+ **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 名称 | 值 | 参数描述 | | ------------------------- | ---- | -------------------------------- | | OVERLAY | 0 | 设置半模态面板在当前UIContext内顶层显示,在所有页面之上。和弹窗类组件显示在一个层级。 | | EMBEDDED | 1 | 设置半模态面板在当前页面内的顶层显示。
**说明:**
目前只支持挂载在Page或者NavDestination节点上,若有NavDestination优先挂载在NavDestination上。只支持在这两种页面内顶层显示。
该模式下新起的页面可以覆盖在半模态弹窗上,页面返回后该半模态依旧存在,半模态面板内容不丢失。
该模式下需确保目标页面节点如Page节点已挂载上树,再拉起半模态,否则半模态将无法挂载到对应的页面节点内。| ## ScrollSizeMode12+ | 名称 | 值 | 参数描述 | | ------------------------- | ---- | -------------------------------- | | FOLLOW_DETENT | 0 | 设置半模态面板跟手滑动结束后更新内容显示区域。 | | CONTINUOUS | 1 | 设置半模态面板在滑动过程中持续更新内容显示区域。| ## DismissSheetAction12+ **原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 | 名称 | 类型 | 必填 | 描述 | | --------------- | ---------------------------------------- | ---- | ------------- | | dismiss | function | 是 | 半模态页面关闭回调函数。开发者需要退出页面时调用。 | | reason | [DismissReason](../js-apis-promptAction.md#dismissreason12枚举说明) | 是 | 返回本次半模态页面退出的操作类型。 | ## SpringBackAction12+ | 名称 | 类型 | 必填 | 描述 | | --------------- | ---------------------------------------- | ---- | ------------- | | springBack | function | 是 | 半模态页面关闭前控制回弹函数,开发者需要半模态回弹时调用。 | ## SheetKeyboardAvoidMode13+枚举说明 | 名称 | 值 | 描述 | | ------------------------- | ---- | -------------------------------- | | NONE | 0 | 设置半模态不避让软键盘。 | | TRANSLATE_AND_RESIZE | 1 | 设置半模态先上抬面板避让软键盘;
当上抬至最大高度仍不足以避让软键盘时,则通过压缩整体内容完成避让。| | RESIZE_ONLY | 2 | 设置半模态通过压缩整体内容避让软键盘。| | TRANSLATE_AND_SCROLL | 3 | 设置半模态先上抬面板避让软键盘;
当上抬至最大高度仍不足以避让软键盘时,则通过滚动内容完成避让。| ## 示例 ### 示例1(不同高度的半模态弹窗) 该示例通过height设置不同高度的半模态弹窗。 ```ts // xxx.ets @Entry @Component struct SheetTransitionExample { @State isShow: boolean = false @State isShow2: boolean = false @State sheetHeight: number = 300; @Builder myBuilder() { Column() { Button("change height") .margin(10) .fontSize(20) .onClick(() => { this.sheetHeight = 500; }) Button("Set Illegal height") .margin(10) .fontSize(20) .onClick(() => { this.sheetHeight = -1; }) Button("close modal 1") .margin(10) .fontSize(20) .onClick(() => { this.isShow = false; }) } .width('100%') .height('100%') } build() { Column() { Button("transition modal 1") .onClick(() => { this.isShow = true }) .fontSize(20) .margin(10) .bindSheet($$this.isShow, this.myBuilder(), { height: this.sheetHeight, backgroundColor: Color.Green, onWillAppear: () => { console.log("BindSheet onWillAppear.") }, onAppear: () => { console.log("BindSheet onAppear.") }, onWillDisappear: () => { console.log("BindSheet onWillDisappear.") }, onDisappear: () => { console.log("BindSheet onDisappear.") } }) } .justifyContent(FlexAlign.Center) .width('100%') .height('100%') } } ``` ![zh-cn_sheet](figures/zh-cn_sheet1.gif) ### 示例2(设置三个不同高度的档位) 使用bindSheet的detents属性设置三个不同高度的档位。 1、dragBar拖拽条只在多个档位高度时生效; 2、区别于height属性在不同时刻设置不同档位的能力,多档位能力有手势切换档位高度的效果,且更适合固定高度区间的场景; 3、若高度范围不确定,且可能存在大于3个不同高度的场景,不建议使用detents属性。 ```ts // xxx.ets @Entry @Component struct SheetTransitionExample { @State isShow: boolean = false @Builder myBuilder() { Column() { Button("content1") .margin(10) .fontSize(20) Button("content2") .margin(10) .fontSize(20) } .width('100%') } build() { Column() { Button("transition modal 1") .onClick(() => { this.isShow = true }) .fontSize(20) .margin(10) .bindSheet($$this.isShow, this.myBuilder(), { detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200], backgroundColor: Color.Gray, blurStyle: BlurStyle.Thick, showClose: true, title: { title: "title", subtitle: "subtitle" }, }) } .justifyContent(FlexAlign.Start) .width('100%') .height('100%') } } ``` ![zh-cn_sheet](figures/zh-cn_sheet2.gif) ### 示例3(使用边框宽度和颜色) bindSheet属性的borderWidth、borderColor属性值使用LocalizedEdgeWidths类型和LocalizedEdgeColors类型。 ```ts // xxx.ets import { LengthMetrics } from '@kit.ArkUI' @Entry @Component struct SheetTransitionExample { @State isShow: boolean = false @Builder myBuilder() { Column() { Button("content1") .margin(10) .fontSize(20) Button("content2") .margin(10) .fontSize(20) } .width('100%') } build() { Column() { Button("transition modal 1") .onClick(() => { this.isShow = true }) .fontSize(20) .margin(10) .bindSheet($$this.isShow, this.myBuilder(), { detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200], backgroundColor: Color.Gray, blurStyle: BlurStyle.Thick, showClose: true, title: { title: "title", subtitle: "subtitle" }, borderWidth: { top: LengthMetrics.vp(10), start: LengthMetrics.vp(10), end: LengthMetrics.vp(20) }, borderColor: { top: Color.Pink, start: Color.Blue, end: Color.Yellow }, }) } .justifyContent(FlexAlign.Start) .width('100%') .height('100%') } } ``` 从左至右显示语言模式示例图 ![zh-cn_sheet](figures/zh-cn_sheet3_ltr.png) 从右至左显示语言模式示例图 ![zh-cn_sheet](figures/zh-cn_sheet3_rtl.png) ### 示例4(使用关闭回调函数) bindSheet注册onWillDismiss与onWillSpringBackWhenDismiss。 ```ts // xxx.ets @Entry @Component struct bindSheetExample { @State isShow: Boolean = false; @Builder myBuilder() { Column() { Button() { Text("CONTEXT") }.height(50) } } build() { Column() { Button("NoRegisterSpringback") .onClick(() => { this.isShow = true }) .fontSize(20) .margin(10) .bindSheet($$this.isShow, this.myBuilder(), { height: SheetSize.MEDIUM, blurStyle: BlurStyle.Thick, showClose: true, title: { title: "title", subtitle: "subtitle" }, preferType: SheetType.CENTER, onWillDismiss: ((DismissSheetAction: DismissSheetAction) => { if (DismissSheetAction.reason == DismissReason.SLIDE_DOWN) { DismissSheetAction.dismiss() //注册dismiss行为 } }), onWillSpringBackWhenDismiss: ((SpringBackAction: SpringBackAction) => { //没有注册springBack, 下拉半模态页面无回弹行为 //SpringBackAction.springBack() }), }) } } } ``` ![zh-cn_sheet](figures/zh-cn_sheet4.gif) ### 示例5(设置内容区刷新时机) ScrollSizeMode.CONTINUOUS 持续更新内容适合detents多档位切换场景。 建议在builder内减少UI加载耗时的操作,滑动时内容实时刷新对性能要求较高。 ```ts // xxx.ets @Entry @Component struct Index { @State isShow: boolean = false; @Builder myBuilder() { Column() { Column() .backgroundColor(Color.Blue) .height(200) .width('100%') Column() .backgroundColor(Color.Green) .height(200) .width('100%') } } build() { Column() { Button('BindSheet') .onClick(() => { this.isShow = true; }) .bindSheet($$this.isShow, this.myBuilder(), { detents: [300, 600, 900], uiContext: this.getUIContext(), mode: SheetMode.OVERLAY, scrollSizeMode: ScrollSizeMode.CONTINUOUS, backgroundColor: Color.Orange, title: { title: 'Title', subtitle: 'Subtitle' } }) } .justifyContent(FlexAlign.Center) .width('100%') .height('100%') } } ``` 跟手触发档位切换时,松手才触发面板内容高度刷新 ![zh-cn_sheet](figures/zh-cn_sheet5_ltr.gif) 跟手触发档位切换时,跟手时期就会触发面板内容高度刷新 ![zh-cn_sheet](figures/zh-cn_sheet5_rtl.gif) ### 示例6(监测键盘高度变化) 在resizeOnly模式下,监测键盘高度变化并根据高度变化做滚动组件的滚动。 ```ts //xxx.ets import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; @Entry @Component struct ListenKeyboardHeightChange { @State isShow: boolean = false; @State avoidMode: SheetKeyboardAvoidMode = SheetKeyboardAvoidMode.RESIZE_ONLY; scroller = new Scroller(); private arr: number[] = [0, 1, 2, 3, 4, 5, 6]; @State scrollHeight: number = 0; @State keyBoardChange: boolean = false; windowClass: window.Window | undefined = undefined; aboutToAppear(): void { try { window.getLastWindow(getContext(this), (err: BusinessError, data) => { const errCode: number = err.code; if (errCode) { console.error(`Failed to obtain the top window, Cause code: ${err.code}, message: ${err.message}`); return; } this.windowClass = data; try { if (this.windowClass !== undefined) { console.log('success in listen height change'); //注册键盘高度变化监听回调 this.windowClass.on('keyboardHeightChange', this.callback); } } catch (exception) { console.error(`Failed to enable the listener for keyboard height changes, Cause code: ${exception.code}, message: ${exception.message}`); } console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data)); }); } catch (exception) { console.error(`Failed to obtain the top window, Cause code: ${exception.code}, message: ${exception.message}`); } } //当键盘高度变化时,设置相应标志位 callback = (height: number) => { this.scrollHeight = height; console.log('height change: ' + this.scrollHeight); if (height !== 0) { this.keyBoardChange = true; } } //当滚动组件高度变化时,根据标志位触发滚动 sizeChangeCallback = (oldValue: SizeOptions, newValue: SizeOptions) => { if (this.keyBoardChange) { this.scroller.scrollBy(0, this.scrollHeight); this.keyBoardChange = false; } } @Builder myBuilder() { Scroll(this.scroller) { Column() { ForEach(this.arr, (item: number) => { Row() { Text(item.toString()) .width('80%') .height(60) .backgroundColor('#3366CC') .borderRadius(15) .fontSize(16) .textAlign(TextAlign.Center) .margin({ top: 5 }) } }, (item: number) => item.toString()) TextInput().height('100') Flex({ alignItems: ItemAlign.End }) { Row() { Button("click") .margin(10) .fontSize(20) .width('45%') Button("cancel") .margin(10) .fontSize(20) .width('45%') }.width('100%') }.height('100%') }.margin({ right: 15 }) } .scrollBar(BarState.On) .scrollable(ScrollDirection.Vertical) .onSizeChange(this.sizeChangeCallback) } build() { Column() { Button("transition modal 1") .onClick(() => { this.isShow = true }) .fontSize(20) .margin(10) .bindSheet($$this.isShow, this.myBuilder(), { detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200], backgroundColor: Color.Gray, blurStyle: BlurStyle.Thick, showClose: true, title: { title: "title", subtitle: "subtitle" }, keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY }) } .justifyContent(FlexAlign.Start) .width('100%') .height('100%') } } ```