• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 半模态转场
2
3通过bindSheet属性为组件绑定半模态页面,在组件插入时可通过设置自定义或默认的内置高度确定半模态大小。
4
5>  **说明:**
6>
7>  从API version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8>
9>  不支持路由跳转。
10
11## bindSheet
12
13bindSheet(isShow: Optional\<boolean\>, builder: CustomBuilder, options?: SheetOptions)
14
15给组件绑定半模态页面,点击后显示模态页面。
16
17**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
18
19**系统能力:** SystemCapability.ArkUI.ArkUI.Full
20
21**参数:**
22
23| 参数名  | 类型                                        | 必填 | 说明                                                         |
24| ------- | ------------------------------------------- | ---- | ------------------------------------------------------------ |
25| isShow  | Optional\<boolean\>                          | 是   | 是否显示半模态页面。<br/>从API version 10开始,该参数支持[$$](../../../ui/state-management/arkts-two-way-sync.md)双向绑定变量。<br />从API version 18开始,该参数支持[!!](../../../ui/state-management/arkts-new-binding.md#组件参数双向绑定)双向绑定变量。|
26| builder | [CustomBuilder](ts-types.md#custombuilder8) | 是   | 配置半模态页面内容。                                         |
27| options | [SheetOptions](#sheetoptions)               | 否   | 配置半模态页面的可选属性。                                   |
28
29> **说明:**
30>
31> 1. 在非双向绑定情况下,以拖拽方式关闭半模态页面不会改变isShow参数的值。
32>
33> 2. 为了使isShow参数值与半模态界面的状态同步,建议使用[$$](../../../ui/state-management/arkts-two-way-sync.md)双向绑定isShow参数。从API version 18开始,该参数支持[!!](../../../ui/state-management/arkts-new-binding.md#组件参数双向绑定)双向绑定变量。
34>
35> 3. 在半模态单挡位向上拖拽或是多挡位上滑换挡情况下,内容在拖拽结束或换挡结束后更新显示区域。
36>
37> 4. 半模态是一个严格和宿主节点绑定在一起的弹窗。若是想实现类似“页面显示的瞬间就弹出半模态”的效果,请确认宿主节点是否已挂载上树。若宿主节点还没上树就将isShow置为true,半模态将不生效。建议使用[onAppear](ts-universal-events-show-hide.md#onappear)函数,确保在宿主节点挂载后再显示半模态。
38> 尤其是 [SheetMode](#sheetmode12枚举说明) = EMBEDDED 时,除宿主节点外,还需确保对应的页面节点成功挂载。
39>
40> 5. 半模态页面的离场动效不支持打断,动效执行期间无法响应其他手势动作。目前离场动效使用[弹簧曲线](../../../ui/arkts-spring-curve.md),该动画曲线存在视觉上并不明显的拖尾动画。因此,在半模态退出时,视觉上半模态页面已经消失,但此时动效可能还未结束,若想再次点击拉起半模态页面则不会响应。需要等动效完全结束后,才可以再次拉起。
41>
42## SheetOptions
43
44继承自[BindOptions](#bindoptions)。
45
46| 名称              | 类型                                       | 必填   | 说明              |
47| --------------- | ---------------------------------------- | ---- | --------------- |
48| height          | [SheetSize](#sheetsize枚举说明)&nbsp;\|&nbsp;[Length](ts-types.md#length) | 否    | 半模态高度,默认是LARGE。<br/>**说明:**<br/>API version 12之前,底部弹窗横屏时该属性设置无效,高度为距离屏幕顶部8vp。<br/>API version 12开始,底部弹窗横屏时该属性设置生效,最大高度为距离屏幕顶部8vp。<br/>API version 14开始,底部弹窗横屏时,无状态栏则最大高度为距离屏幕顶部8vp,有状态栏则最大高度为距离状态栏8vp。<br/>底部弹窗时,当设置detents时,该属性设置无效。<br/>底部弹窗竖屏时,最大高度为距离状态栏8vp。<br />居中弹窗和跟手弹窗设置类型为SheetSize.LARGESheetSize.MEDIUM无效,显示默认高度560vp。居中弹窗和跟手弹窗最小高度为320vp,最大高度为窗口短边的90%。当使用Length设置的高度和使用SheetSize.FIT_CONTENT自适应的高度大于最大高度,则显示最大高度,小于最小高度,则显示最小高度。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
49| detents<sup>11+</sup> | [([SheetSize](#sheetsize枚举说明) \| [Length](ts-types.md#length)), ( [SheetSize](#sheetsize枚举说明) \| [Length](ts-types.md#length))?, ([SheetSize](#sheetsize枚举说明) \| [Length](ts-types.md#length))?] | 否 | 半模态页面的切换高度档位。<br/>**说明:**<br/>从API version 12开始,底部弹窗横屏时该属性设置生效。<br/>底部弹窗竖屏生效,元组中第一个高度为初始高度。<br />面板可跟手滑动切换档位,松手后是否滑动至目标档位有两个判断条件:速度和距离。速度超过阈值,则执行滑动至与手速方向一致的目标档位;速度小于阈值,则引入距离判断条件,当位移距离>当前位置与目标位置的1/2,滑动至与手速方向一致的目标档位,位移距离当前位置与目标位置的1/2,返回至当前档位。速度阈值:1000,距离阈值:50%。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
50| preferType<sup>11+</sup> | [SheetType](#sheettype11枚举说明) | 否 | 半模态页面的样式。<br/>**说明:**<br/>半模态在不同窗口所支持的显示类型:<br/>1. 宽度 < 600vp:底部。<br/>2. 600vp <= 宽度 < 840vp:底部、居中、跟手。默认居中样式。<br/>3. 宽度 >= 840vp:底部、居中、跟手。默认跟手样式。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
51| showClose<sup>11+</sup> | boolean \| [Resource](ts-types.md#resource) | 否 | 是否显示关闭图标,默认显示。<br/> 2in1设备默认无按钮底板。<br/>**说明:**<br/>Resource需要为boolean类型。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
52| dragBar         | boolean                                  | 否    | 是否显示控制条。<br/>**说明:**<br/>半模态面板的detents属性设置多个不同高度并且设置生效时,默认显示控制条。否则不显示控制条。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
53| blurStyle<sup>11+</sup> | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | 否 | 半模态面板的模糊背景。默认无模糊背景。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
54| maskColor | [ResourceColor](ts-types.md#resourcecolor) | 否 | 半模态页面的背景蒙层颜色。<br/>**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
55| title<sup>11+</sup> | [SheetTitleOptions](#sheettitleoptions11) \| [CustomBuilder](ts-types.md#custombuilder8) | 否 | 半模态面板的标题。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
56| enableOutsideInteractive<sup>11+</sup> | boolean | 否 | 半模态所在页面是否允许交互。<br/>**说明:**<br/>设置为true时允许交互,不显示蒙层;设置为false时不允许交互,显示蒙层;若不进行设置,默认底部弹窗与居中弹窗不允许交互,跟手弹窗允许交互。当设置为true时,maskColor设置无效。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
57| shouldDismiss<sup>11+</sup> | (sheetDismiss: [SheetDismiss](#sheetdismiss11)) => void | 否 | 半模态页面交互式关闭回调函数。<br/>**说明:**<br/>当用户执行下拉关闭、触发back事件、点击遮罩层关闭或关闭按钮的交互操作时,如果已注册回调函数,模态窗口将不会立即关闭。要关闭半模态,需在回调函数中调用shouldDismiss.dismiss()方法来实现。<br/>如果不注册该回调函数,则用户执行下拉关闭、触发back事件、点击遮罩层关闭或关闭按钮的交互操作时,正常关闭半模态,无其他行为。<br/>建议在[二次确认](../../../ui/arkts-sheet-page.md#二次确认能力)场景使用。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
58| onWillDismiss<sup>12+</sup> | [DismissSheetAction](#dismisssheetaction12) | 否    | 半模态页面的交互式关闭回调函数允许开发者注册,以获取关闭操作的类型,并决定是否关闭半模态状态。<br/>**说明:**<br />当用户触发关闭操作时,若已注册回调函数,则不会立即关闭页面,而是由开发者通过回调函数中的[reason](../js-apis-promptAction.md#dismissreason12枚举说明)参数判断关闭操作的类型,进而根据具体原因自主选择是否关闭半模态页面。<br/>如果不注册该回调函数,则用户执行关闭操作时,正常关闭半模态,无其他行为。<br />在onWillDismiss回调中,不能再做onWillDismiss拦截。<br />建议在[二次确认](../../../ui/arkts-sheet-page.md#二次确认能力)场景使用。<br />**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
59| onWillSpringBackWhenDismiss<sup>12+</sup> | [SpringBackAction](#springbackaction12) | 否    | 半模态页面交互式关闭前控制回弹函数允许开发者注册,以控制半模态页面交互式关闭时的回弹效果。<br/>**说明:**<br />当用户触发执行下拉关闭操作并同时注册该回调函数与shouldDimiss或onWillDismiss时,由开发者控制下滑关闭时是否回弹。在回调函数中可以通过调用springBack来实现回弹效果。也可以通过不调用springBack来取消回弹效果。<br />若不注册该回调函数,但注册shouldDimiss或onWillDismiss时,则默认在下滑关闭时,会触发回弹效果,回弹后再根据shouldDimiss或onWillDismiss内的回调行为决定半模态是否关闭。<br />如果不注册该回调函数,且未注册shouldDimiss或onWillDismiss时,默认在下滑关闭时,触发半模态关闭。<br />**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
60| onHeightDidChange<sup>12+</sup> | Callback&lt;number&gt; | 否 | 半模态页面高度变化回调函数。<br/>**说明:**<br/>底部弹窗时,只有档位变化和拖拽跟手才返回每一帧高度,拉起半模态和避让软键盘只返回最后的高度,其他弹窗只在半模态拉起返回最后高度。<br/>返回值为px。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
61| onDetentsDidChange<sup>12+</sup> | Callback&lt;number&gt; | 否 | 半模态页面档位变化回调函数。<br/>**说明:**<br/>底部弹窗时,档位变化返回最后的高度。<br/>返回值为px。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
62| onWidthDidChange<sup>12+</sup> | Callback&lt;number&gt; | 否 | 半模态页面宽度变化回调函数。<br/>**说明:**<br/>宽度变化时返回最后的宽度。<br/>返回值为px。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
63| onTypeDidChange<sup>12+</sup> | Callback&lt;[SheetType](#sheettype11枚举说明)&gt; | 否 | 半模态页面形态变化回调函数。<br/>**说明:**<br/>形态变化时返回最后的形态。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
64| borderWidth<sup>12+</sup> | [Dimension](ts-types.md#dimension10)&nbsp;\|&nbsp;[EdgeWidths](ts-types.md#edgewidths9)&nbsp;\|&nbsp;[LocalizedEdgeWidths](ts-types.md#localizededgewidths12)<sup>12+</sup>  | 否 | 设置半模态页面的边框宽度。<br />可分别设置4个边框宽度。<br />默认值:0<br /> 百分比参数方式:以父元素半模态页面宽的百分比来设置半模态页面的边框宽度。<br />当半模态页面左边框和右边框大于半模态页面宽度,半模态页面上边框和下边框大于半模态页面高度,显示可能不符合预期。<br />**说明:**<br />底部弹窗时,底部边框宽度设置无效。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
65| borderColor<sup>12+</sup> | [ResourceColor](ts-types.md#resourcecolor)&nbsp;\|&nbsp;[EdgeColors](ts-types.md#edgecolors9)&nbsp;\|&nbsp;[LocalizedEdgeColors](ts-types.md#localizededgecolors12)<sup>12+</sup>  | 否 | 设置半模态页面的边框颜色。<br/>默认值:Color.Black<br/> 如果使用borderColor属性,需要和borderWidth属性一起使用。 <br />**说明:**<br />底部弹窗时,底部边框颜色设置无效。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
66| borderStyle<sup>12+</sup> | [BorderStyle](ts-appendix-enums.md#borderstyle)&nbsp;\|&nbsp;[EdgeStyles](ts-types.md#edgestyles9)  | 否 | 设置半模态页面的边框样式。<br/>默认值:BorderStyle.Solid<br/>如果使用borderStyle属性,需要和borderWidth属性一起使用。 <br />**说明:**<br />底部弹窗时,底部边框样式设置无效。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
67| width<sup>12+</sup> | [Dimension](ts-types.md#dimension10)   | 否 | 设置半模态页面的宽度。<br /> 百分比参数方式:以父元素宽的百分比来设置半模态页面的宽度。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
68| shadow<sup>12+</sup> | [ShadowOptions](ts-universal-attributes-image-effect.md#shadowoptions对象说明)&nbsp;\|&nbsp;[ShadowStyle](ts-universal-attributes-image-effect.md#shadowstyle10枚举说明)   | 否 | 设置半模态页面的阴影。<br />2in1设备默认值:ShadowStyle.OUTER_FLOATING_SM。 <br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
69| uiContext<sup>12+</sup> | [UIContext](../js-apis-arkui-UIContext.md#uicontext)   | 否 | 在UIContext实例对应的窗口中显示半模态。<br />**说明:**<br />使用[openBindSheet](../js-apis-arkui-UIContext.md#openbindsheet12)启动的半模态页面,不支持设置、更新该属性。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。|
70| mode<sup>12+</sup> | [SheetMode](#sheetmode12枚举说明)   | 否 | 设置半模态页面的显示层级。<br/>默认值:SheetMode.OVERLAY<br />**说明:**<br /> 1. 半模态显示期间mode属性不支持动态切换,两种模式的显示层级完全不同,无法做到显示期间同一个半模态从一个层级变换到另一个层级。建议在使用时明确诉求固定mode值。 <br/> 2. 设置SheetMode.EMBEDDED时不支持设置UIContext属性,两者对应的半模态显示层级效果互相冲突。<br />3. 使用[openBindSheet](../js-apis-arkui-UIContext.md#openbindsheet12)启动半模态页面,若未传入有效的targetId,则不支持设置为SheetMode.EMBEDDED,默认为SheetMode.OVERLAY。<br/>**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
71| scrollSizeMode<sup>12+</sup> | [ScrollSizeMode](#scrollsizemode12枚举说明)   | 否 | 设置半模态面板滑动时,内容区域刷新时机。<br/>默认值:ScrollSizeMode.FOLLOW_DETENT |
72| keyboardAvoidMode<sup>13+</sup> | [SheetKeyboardAvoidMode](#sheetkeyboardavoidmode13枚举说明) | 否 | 设置半模态激活输入法时对软键盘的避让方式。<br/> **默认值:** TRANSLATE_AND_SCROLL<br/>**原子化服务API:** 从API version 13开始,该接口支持在原子化服务中使用。 |
73| enableHoverMode<sup>14+</sup>              | boolean | 否   | 是否响应悬停态。<br />默认值:false,默认不响应。<br />**说明:**<br />底部弹窗样式和跟手弹窗样式不响应悬停态。|
74| hoverModeArea<sup>14+</sup>              | [HoverModeAreaType](ts-appendix-enums.md#hovermodeareatype14) | 否   | 悬停态下弹窗默认展示区域。<br />默认值:HoverModeAreaType.BOTTOM_SCREEN |
75| radius<sup>15+</sup> | [LengthMetrics](../js-apis-arkui-graphics.md#lengthmetrics12)&nbsp;\|&nbsp;[BorderRadiuses](ts-types.md#borderradiuses9)&nbsp;\|&nbsp;[LocalizedBorderRadiuses](ts-types.md#LocalizedBorderRadiuses12) | 否 | 设置半模态页面圆角半径。<br/>不建议设置4个圆角大小不相等,圆角大小相等时面板视觉体验最佳。<br/>**默认值**:32vp<br/>**说明:**<br/>1. 根据设置的圆角半径值显示,如果未设置,则使用默认值。底部样式不显示半模态底部2个圆角,即使设置了底部2个圆角也不生效。<br/>2. 分别设置4个方向的圆角半径后,如果某个方向的值异常,异常方向的圆角值重置为默认值,非异常方向的圆角值为已设置的值。统一设置4个方向的圆角时,如果设置的值异常,4个方向的圆角都重置为默认值。<br/>3. 半径设置为百分比时,以半模态页面的宽度为基准。<br/>4. 当圆角的半径大于半模态页面宽度一半时,圆角的半径取值为半模态页面宽度的一半。<br/>5. 当半模态页面高度过小且圆角半径设置过大时,可能导致显示异常。<br/>**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 |
76| detentSelection<sup>15+</sup>         <br> | [SheetSize](#sheetsize枚举说明)&nbsp;\|&nbsp;[Length](ts-types.md#length) | 否    | 支持非手势切换挡位。<br />**默认值:** detents[0]。<br/>**说明:**<br/>1. 该接口取值范围为detents数组范围,若设值非detents范围,该接口无效。<br/>2. 当设置SheetSize.FIT_CONTENT时,该接口无效。<br>3. 不建议手势切换挡位与该接口切换挡位同时生效使用。<br/>**原子化服务API:** 从API version 15开始,该接口支持在原子化服务中使用。 |
77| placement<sup>18+</sup> | [Placement](ts-appendix-enums.md#placement8) | 否 | 设置半模态popup样式弹窗相对于目标的显示位置。<br />默认值:Placement.Bottom<br />**说明:** <br /> 1. popup样式弹窗在确保指定位置能容纳弹窗尺寸的前提下,优先依据设定的placement展示弹窗。若不可行,则遵循先垂直翻转,后尝试90°水平旋转的规则调整显示位置,以预设方向为下方为例,调整顺序依次为:下、上、右、左。<br />2. 如果设置的对齐方式导致组件布局超出窗口范围,将根据该对齐方式在水平或垂直方向上进行位移,直至组件完全显示在窗口内。<br />3. 如果在四个方向上均无法容纳当前的popup样式弹窗,处理方式遵循开发者设置的placementOnTarget属性:<br />1)若属性值为true,将依据设定的placement,向其镜像方向平移,直至弹窗能够完全显示。<br />2)若属性值为false,则在四个方向中,选择能够完全展示弹窗宽度且剩余高度最大的方向,通过调整半模态高度以适应当前方向,确保弹窗能够放下,同时保持预设placement对应的对齐方式不变。 <br />**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 |
78| placementOnTarget<sup>18+</sup> | Boolean | 否 | 半模态popup样式弹窗在当前窗口下,四个方向均无法容纳该弹窗大小时,设置是否允许其覆盖在目标节点上。<br /> 默认值:true <br />**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。|
79| effectEdge<sup>18+</sup> | number | 否 | 设置半模态面板边缘滚动,支持单边生效。<br/>**默认值**:默认双边生效,即[EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).START \| [EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).END(即数值3)。<br />**说明:**<br />1. 仅上边缘生效:[EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).START。<br/>2. 仅下边缘生效:[EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).END。<br/>3. 双边生效:[EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).START \| [EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).END(即数值3)。<br/>4. 双边不生效:[EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).START & [EffectEdge](ts-container-scrollable-common.md#effectedge18枚举说明).END(即数值0)。<br />**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 |
80| showInSubWindow<sup>18+</sup> | boolean                                  | 否    | 半模态是否在独立子窗中显示。<br>默认值:false<br>**说明**:<br>1.若属性值为true,半模态可以在独立子窗口中展示,并且可以超过应用窗口范围。<br>2.若属性值为false,半模态只能在应用窗口范围内展示。<br>3. 不建议在showInSubWindow为true的弹窗触发显示另一个showInSubWindow为true的弹窗,半模态可能会影响其他组件行为。<br>4. 不建议在showInSubWindow为true的弹窗中使用CalendarPicker、CalendarPickerDialog、DatePickerDialog、TextPickerDialog、TimePickerDialog等picker组件,半模态会影响上述组件行为。<br>5. 半模态显示期间该属性不支持动态切换。<br/>**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 |
81
82## SheetSize枚举说明
83
84指定半模态的高度。
85
86| 名称                      | 值    | 说明                         |
87| ------------------------- | ---- | -------------------------------- |
88| MEDIUM                    | 0    | 指定半模态高度为屏幕高度一半。<br />**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。   |
89| LARGE                     | 1    | 指定半模态高度几乎为屏幕高度。<br />**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。   |
90| FIT_CONTENT<sup>11+</sup> | 2    | 指定半模态高度为适应内容的高度。<br />**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。<br />**说明:**<br />FIT_CONTENT是半模态容器高度去适应孩子builder根节点的布局。此场景下builder根节点的高度不能使用百分比,两者不能相互依赖彼此的布局。 |
91
92## BindOptions
93
94半模态、全模态的公共配置接口。
95
96| 名称            | 类型                                       | 必填 | 说明                     |
97| --------------- | ------------------------------------------ | ---- | ------------------------ |
98| backgroundColor | [ResourceColor](ts-types.md#resourcecolor) | 否   | 半模态页面的背板颜色。<br />默认值:Color.White。<br />**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
99| onWillAppear<sup>12+</sup>        | () => void                                 | 否   | 半模态页面显示(动画开始前)回调函数。**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
100| onAppear        | () => void                                 | 否   | 半模态页面显示(动画结束后)回调函数。<br />**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
101| onWillDisappear<sup>12+</sup>     | () => void                                 | 否   | 半模态页面回退(动画开始前)回调函数。<br />**说明:**<br />不允许在onWillDisappear函数中修改状态变量,可能会导致组件行为不稳定。**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 |
102| onDisappear     | () => void                                 | 否   | 半模态页面回退(动画结束后)回调函数。<br />**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 |
103
104## SheetType<sup>11+</sup>枚举说明
105
106半模态弹窗的样式。
107
108**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
109
110| 名称   | 值   | 说明                                               |
111| ------ | ---- | ------------------------------------------------------ |
112| BOTTOM | 0    | 底部弹窗。                                             |
113| CENTER | 1    | 居中弹窗。                                             |
114| POPUP  | 2    | 跟手弹窗。跟手弹窗面板不支持跟手滑动,下滑面板不关闭。 |
115
116## SheetDismiss<sup>11+</sup>
117
118控制半模态的关闭。
119
120**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
121
122| 名称    | 类型       | 必填 | 说明                                                         |
123| ------- | ---------- | ---- | ------------------------------------------------------------ |
124| dismiss | () => void | 是   | 半模态面板关闭回调函数。开发者需要退出时调用,不需要退出时无需调用。 |
125
126## SheetTitleOptions<sup>11+</sup>
127
128半模态面板的标题。
129
130**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
131
132| 名称     | 类型                                   | 必填 | 说明                 |
133| -------- | -------------------------------------- | ---- | -------------------- |
134| title    | [ResourceStr](ts-types.md#resourcestr) | 是   | 半模态面板的主标题。 |
135| subtitle | [ResourceStr](ts-types.md#resourcestr) | 否   | 半模态面板的副标题。 |
136
137## SheetMode<sup>12+</sup>枚举说明
138
139半模态的显示层级模式。
140
141**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
142
143| 名称                      | 值   | 说明                         |
144| ------------------------- | ---- | -------------------------------- |
145| OVERLAY                   | 0    | 设置半模态面板在当前UIContext内顶层显示,在所有页面之上。和弹窗类组件显示在一个层级。   |
146| EMBEDDED                  | 1    | 设置半模态面板在当前页面内的顶层显示。 <br />**说明:**<br />目前只支持挂载在Page或者NavDestination节点上,若有NavDestination优先挂载在NavDestination上。只支持在这两种页面内顶层显示。<br /> 该模式下新起的页面可以覆盖在半模态弹窗上,页面返回后该半模态依旧存在,半模态面板内容不丢失。 <br /> 该模式下需确保目标页面节点如Page节点已挂载上树,再拉起半模态,否则半模态将无法挂载到对应的页面节点内。|
147
148## ScrollSizeMode<sup>12+</sup>枚举说明
149
150半模态面板上下滑动时的内容更新方式。
151
152| 名称           | 值   | 说明                         |
153| ------------------------- | ---- | -------------------------------- |
154| FOLLOW_DETENT | 0    | 设置半模态面板跟手滑动结束后更新内容显示区域。   |
155| CONTINUOUS    | 1    | 设置半模态面板在滑动过程中持续更新内容显示区域。|
156
157## DismissSheetAction<sup>12+</sup>
158
159半模态关闭前的回调。
160
161**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
162
163| 名称              | 类型                                       | 必填   | 说明            |
164| --------------- | ---------------------------------------- | ---- | ------------- |
165| dismiss | function | 是    | 半模态页面关闭回调函数。开发者需要退出页面时调用。 |
166| reason | [DismissReason](../js-apis-promptAction.md#dismissreason12枚举说明) | 是    | 返回本次半模态页面退出的操作类型。  |
167
168## SpringBackAction<sup>12+</sup>
169
170控制半模态关闭前的回弹。
171
172| 名称              | 类型                                       | 必填   | 说明            |
173| --------------- | ---------------------------------------- | ---- | ------------- |
174| springBack | function | 是    | 半模态页面关闭前控制回弹函数,开发者需要半模态回弹时调用。  |
175
176## SheetKeyboardAvoidMode<sup>13+</sup>枚举说明
177
178| 名称           | 值   | 说明                         |
179| ------------------------- | ---- | -------------------------------- |
180| NONE | 0    | 设置半模态不避让软键盘。   |
181| TRANSLATE_AND_RESIZE    | 1    | 设置半模态先上抬面板避让软键盘;<br/>当上抬至最大高度仍不足以避让软键盘时,则通过压缩整体内容完成避让。|
182| RESIZE_ONLY    | 2    | 设置半模态通过压缩整体内容避让软键盘。|
183| TRANSLATE_AND_SCROLL    | 3    | 设置半模态先上抬面板避让软键盘;<br/>当上抬至最大高度仍不足以避让软键盘时,则通过滚动内容完成避让。|
184
185## 示例
186### 示例1(不同高度的半模态弹窗)
187
188该示例通过height设置不同高度的半模态弹窗。
189
190```ts
191// xxx.ets
192@Entry
193@Component
194struct SheetTransitionExample {
195  @State isShow: boolean = false
196  @State sheetHeight: number = 300;
197
198  @Builder
199  myBuilder() {
200    Column() {
201      Button("change height")
202        .margin(10)
203        .fontSize(20)
204        .onClick(() => {
205          this.sheetHeight = 500;
206        })
207
208      Button("Set Illegal height")
209        .margin(10)
210        .fontSize(20)
211        .onClick(() => {
212          this.sheetHeight = -1;
213        })
214
215      Button("close modal 1")
216        .margin(10)
217        .fontSize(20)
218        .onClick(() => {
219          this.isShow = false;
220        })
221    }
222    .width('100%')
223    .height('100%')
224  }
225
226  build() {
227    Column() {
228      Button("transition modal 1")
229        .onClick(() => {
230          this.isShow = true
231        })
232        .fontSize(20)
233        .margin(10)
234        .bindSheet($$this.isShow, this.myBuilder(), {
235          height: this.sheetHeight,
236          backgroundColor: Color.Green,
237          onWillAppear: () => {
238            console.log("BindSheet onWillAppear.")
239          },
240          onAppear: () => {
241            console.log("BindSheet onAppear.")
242          },
243          onWillDisappear: () => {
244            console.log("BindSheet onWillDisappear.")
245          },
246          onDisappear: () => {
247            console.log("BindSheet onDisappear.")
248          }
249        })
250    }
251    .justifyContent(FlexAlign.Center)
252    .width('100%')
253    .height('100%')
254  }
255}
256```
257
258![zh-cn_sheet](figures/zh-cn_sheet1.gif)
259
260### 示例2(设置三个不同高度的档位)
261
262使用bindSheet的detents属性设置三个不同高度的档位。
2631、dragBar拖拽条只在多个档位高度时生效;
2642、区别于height属性在不同时刻设置不同档位的能力,多档位能力有手势切换档位高度的效果,且更适合固定高度区间的场景;
2653、若高度范围不确定,且可能存在大于3个不同高度的场景,不建议使用detents属性。
266
267```ts
268// xxx.ets
269@Entry
270@Component
271struct SheetTransitionExample {
272  @State isShow: boolean = false
273
274  @Builder
275  myBuilder() {
276    Column() {
277      Button("content1")
278        .margin(10)
279        .fontSize(20)
280
281      Button("content2")
282        .margin(10)
283        .fontSize(20)
284    }
285    .width('100%')
286  }
287
288  build() {
289    Column() {
290      Button("transition modal 1")
291        .onClick(() => {
292          this.isShow = true
293        })
294        .fontSize(20)
295        .margin(10)
296        .bindSheet($$this.isShow, this.myBuilder(), {
297          detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
298          blurStyle: BlurStyle.Thick,
299          showClose: true,
300          title: { title: "title", subtitle: "subtitle" },
301        })
302    }
303    .justifyContent(FlexAlign.Start)
304    .width('100%')
305    .height('100%')
306  }
307}
308```
309
310![zh-cn_sheet](figures/zh-cn_sheet2.gif)
311
312### 示例3(使用边框宽度和颜色)
313
314bindSheet属性的borderWidth、borderColor属性值使用LocalizedEdgeWidths类型和LocalizedEdgeColors类型。
315
316```ts
317// xxx.ets
318import { LengthMetrics } from '@kit.ArkUI'
319
320@Entry
321@Component
322struct SheetTransitionExample {
323  @State isShow: boolean = false
324
325  @Builder
326  myBuilder() {
327    Column() {
328      Button("content1")
329        .margin(10)
330        .fontSize(20)
331
332      Button("content2")
333        .margin(10)
334        .fontSize(20)
335    }
336    .width('100%')
337  }
338
339  build() {
340    Column() {
341      Button("transition modal 1")
342        .onClick(() => {
343          this.isShow = true
344        })
345        .fontSize(20)
346        .margin(10)
347        .bindSheet($$this.isShow, this.myBuilder(), {
348          detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
349          backgroundColor: Color.Gray,
350          blurStyle: BlurStyle.Thick,
351          showClose: true,
352          title: { title: "title", subtitle: "subtitle" },
353          borderWidth: { top: LengthMetrics.vp(10), start: LengthMetrics.vp(10), end: LengthMetrics.vp(20) },
354          borderColor: { top: Color.Pink, start: Color.Blue, end: Color.Yellow },
355        })
356    }
357    .justifyContent(FlexAlign.Start)
358    .width('100%')
359    .height('100%')
360  }
361}
362```
363
364从左至右显示语言模式示例图
365
366![zh-cn_sheet](figures/zh-cn_sheet3_ltr.png)
367
368从右至左显示语言模式示例图
369
370![zh-cn_sheet](figures/zh-cn_sheet3_rtl.png)
371
372### 示例4(使用关闭回调函数)
373
374bindSheet注册onWillDismiss与onWillSpringBackWhenDismiss。
375
376```ts
377// xxx.ets
378@Entry
379@Component
380struct bindSheetExample {
381  @State isShow: Boolean = false;
382
383  @Builder
384  myBuilder() {
385    Column() {
386      Button() {
387        Text("CONTEXT")
388      }.height(50)
389    }
390  }
391
392  build() {
393    Column() {
394      Button("NoRegisterSpringback")
395        .onClick(() => {
396          this.isShow = true
397        })
398        .fontSize(20)
399        .margin(10)
400        .bindSheet($$this.isShow, this.myBuilder(), {
401          height: SheetSize.MEDIUM,
402          blurStyle: BlurStyle.Thick,
403          showClose: true,
404          title: { title: "title", subtitle: "subtitle" },
405          preferType: SheetType.CENTER,
406
407
408          onWillDismiss: ((DismissSheetAction: DismissSheetAction) => {
409            if (DismissSheetAction.reason == DismissReason.SLIDE_DOWN) {
410              DismissSheetAction.dismiss() //注册dismiss行为
411            }
412          }),
413
414          onWillSpringBackWhenDismiss: ((SpringBackAction: SpringBackAction) => {
415            //没有注册springBack, 下拉半模态页面无回弹行为
416            //SpringBackAction.springBack()
417          }),
418        })
419    }
420  }
421}
422```
423![zh-cn_sheet](figures/zh-cn_sheet4.gif)
424
425### 示例5(设置内容区刷新时机)
426
427ScrollSizeMode.CONTINUOUS 持续更新内容适合detents多档位切换场景。
428建议在builder内减少UI加载耗时的操作,滑动时内容实时刷新对性能要求较高。
429
430```ts
431// xxx.ets
432@Entry
433@Component
434struct Index {
435  @State isShow: boolean = false;
436
437  @Builder
438  myBuilder() {
439    Column() {
440      Column()
441        .backgroundColor(Color.Blue)
442        .height(200)
443        .width('100%')
444      Column()
445        .backgroundColor(Color.Green)
446        .height(200)
447        .width('100%')
448    }
449  }
450
451  build() {
452    Column() {
453      Button('BindSheet')
454        .onClick(() => {
455          this.isShow = true;
456        })
457        .bindSheet($$this.isShow, this.myBuilder(), {
458          detents: [300, 600, 900],
459          uiContext: this.getUIContext(),
460          mode: SheetMode.OVERLAY,
461          scrollSizeMode: ScrollSizeMode.CONTINUOUS,
462          backgroundColor: Color.Orange,
463          title: { title: 'Title', subtitle: 'Subtitle' }
464        })
465    }
466    .justifyContent(FlexAlign.Center)
467    .width('100%')
468    .height('100%')
469  }
470}
471```
472跟手触发档位切换时,松手才触发面板内容高度刷新
473
474![zh-cn_sheet](figures/zh-cn_sheet5_ltr.gif)
475
476跟手触发档位切换时,跟手时期就会触发面板内容高度刷新
477
478![zh-cn_sheet](figures/zh-cn_sheet5_rtl.gif)
479
480### 示例6(设置压缩模态内容)
481
482通过设置SheetKeyboardAvoidMode为RESIZE_ONLY,当键盘高度变化时,根据高度变化实现滚动组件的滚动。
483
484```ts
485//xxx.ets
486import window from '@ohos.window';
487import { BusinessError } from '@ohos.base';
488
489@Entry
490@Component
491struct ListenKeyboardHeightChange {
492  @State isShow: boolean = false;
493  @State avoidMode: SheetKeyboardAvoidMode = SheetKeyboardAvoidMode.RESIZE_ONLY;
494  scroller = new Scroller();
495  private arr: number[] = [0, 1, 2, 3, 4, 5, 6];
496  windowClass: window.Window | undefined = undefined;
497
498  aboutToAppear(): void {
499    try {
500      window.getLastWindow(this.getUIContext().getHostContext(), (err: BusinessError, data) => {
501        const errCode: number = err.code;
502        if (errCode) {
503          console.error(`Failed to obtain the top window, Cause code: ${err.code}, message: ${err.message}`);
504          return;
505        }
506        this.windowClass = data;
507        try {
508          if (this.windowClass !== undefined) {
509            console.log('success in listen height change');
510            this.windowClass.on('keyboardHeightChange', this.callback);
511          }
512        } catch (exception) {
513          console.error(`Failed to enable the listener for keyboard height changes, Cause code: ${exception.code}, message: ${exception.message}`);
514        }
515        console.info('Succeeded in obtaining the top window. Data: ' + JSON.stringify(data));
516      });
517    } catch (exception) {
518      console.error(`Failed to obtain the top window, Cause code: ${exception.code}, message: ${exception.message}`);
519    }
520  }
521
522  callback = (height: number) => {
523    console.log('height change: ' + height);
524    if (height !== 0) {
525      this.scroller.scrollTo({
526        xOffset: 0, yOffset: height + this.scroller.currentOffset().yOffset,
527        animation: { duration: 1000, curve: Curve.Ease, canOverScroll: false }
528      });
529    }
530  }
531
532  @Builder
533  myBuilder() {
534    Scroll(this.scroller) {
535      Column() {
536        ForEach(this.arr, (item: number) => {
537          Row() {
538            Text(item.toString())
539              .width('80%')
540              .height(60)
541              .backgroundColor('#3366CC')
542              .borderRadius(15)
543              .fontSize(16)
544              .textAlign(TextAlign.Center)
545              .margin({ top: 5 })
546          }
547        }, (item: number) => item.toString())
548
549        TextInput().height('100')
550
551        Flex({ alignItems: ItemAlign.End }) {
552          Row() {
553            Button("click")
554              .margin(10)
555              .fontSize(20)
556              .width('45%')
557
558            Button("cancel")
559              .margin(10)
560              .fontSize(20)
561              .width('45%')
562          }.width('100%')
563        }.height(100)
564      }.margin({ right: 15, bottom: 50 })
565    }
566    .height('100%')
567    .scrollBar(BarState.On)
568    .scrollable(ScrollDirection.Vertical)
569  }
570
571  build() {
572    Column() {
573      Button("transition modal 1")
574        .onClick(() => {
575          this.isShow = true
576        })
577        .fontSize(20)
578        .margin(10)
579        .bindSheet($$this.isShow, this.myBuilder(), {
580          height: 750,
581          backgroundColor: Color.Gray,
582          blurStyle: BlurStyle.Thick,
583          showClose: true,
584          title: { title: "title", subtitle: "subtitle" },
585          keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY,
586        })
587    }
588    .justifyContent(FlexAlign.Start)
589    .width('100%')
590    .height('100%')
591  }
592}
593```
594![zh-cn_sheet](figures/zh-cn_sheet6.gif)
595
596### 示例7(镜像场景下如何设置圆角属性)
597
598此示例为说明镜像场景而设置了不同的圆角半径,通常不建议开发者设置不同的值,会造成视觉体验不佳。
599
600其中,半模态的radius属性值使用LocalizedBorderRadiuses类型。
601
602```ts
603import { LengthMetrics } from '@kit.ArkUI';
604
605@Entry
606@Component
607struct SheetTransitionExample {
608  @State isShow: boolean = false
609
610  @Builder
611  myBuilder() {
612    Column() {
613      Button("content1")
614        .margin(10)
615        .fontSize(20)
616
617      Button("content2")
618        .margin(10)
619        .fontSize(20)
620    }
621    .width('100%')
622  }
623
624  build() {
625    Column() {
626      Button("transition modal 1")
627        .onClick(() => {
628          this.isShow = true
629        })
630        .fontSize(20)
631        .margin(10)
632        .bindSheet($$this.isShow, this.myBuilder(), {
633          detents: [SheetSize.MEDIUM, SheetSize.LARGE, 200],
634          title: { title: "title", subtitle: "subtitle" },
635          radius: { topStart: LengthMetrics.vp(50), topEnd: LengthMetrics.vp(10) },
636        })
637    }
638    .justifyContent(FlexAlign.Start)
639    .width('100%')
640    .height('100%')
641  }
642}
643```
644
645从左至右显示语言模式示例图
646
647![zh-cn_sheet](figures/zh-cn_sheet7_ltr.png)
648
649从右至左显示语言模式示例图
650
651![zh-cn_sheet](figures/zh-cn_sheet7_rtl.png)
652