HarmonyOS 鸿蒙Next中模态转场如何实现上拉/下拉到固定高度后,不再跟手滑动,像华为地图/高德地图首页的那种效果?
HarmonyOS 鸿蒙Next中模态转场如何实现上拉/下拉到固定高度后,不再跟手滑动,像华为地图/高德地图首页的那种效果? 如何禁止半模态弹窗的跟手滑动功能
【背景知识】
- bindSheet能够给组件绑定半模态页面,
- 通用属性zIndex能够设置组件的堆叠顺序,在同一容器中显示兄弟组件的层级关系。通用属性visibility能够控制组件的显示或隐藏,实现不同的显隐控制效果。
【解决方案】
bindSheet不支持关闭弹窗的跟手滑动功能,可以通过自定义弹出视图实现类似半模态弹窗的效果,即可避免跟手滑动功能,替代半模态弹窗效果具体实现如下: 使用@Provide装饰器和@Consume装饰器实现Index组件和CustomAlert的双向绑定,通过变量panelHeight和zIndexd控制CustomAlert组件的zIndex属性和visibility属性,从而控制CustomAlert组件的显隐,实现类似半模态页面弹出的效果,示例代码如下:
@Entry
@Component
struct Index {
@Provide('panelHeight') panelHeight: string = '0'
@Provide('zIndexd') zIndexd: number = 0
build() {
Stack({ alignContent: Alignment.Bottom }) {
Column() {
Button('弹起')
.onClick(() => {
if (this.panelHeight === '0') {
this.panelHeight = '40%'
this.zIndexd = 2
} else {
this.panelHeight = '0'
this.zIndexd = 0
}
})
}
.height('100%')
.width('100%')
.backgroundColor(Color.White)
.zIndex(1)
Column() {
}
.height('100%')
.width('100%')
.backgroundColor(Color.Black)
.opacity(0.10)
.zIndex(this.zIndexd)
.onClick(() => {
this.panelHeight = '0'
this.zIndexd = 0
})
CustomAlert()
.height(this.panelHeight)
.visibility(this.panelHeight === '0' ? Visibility.Hidden : Visibility.Visible)
.animation({ duration: 300 })
.zIndex(2)
}
}
}
@Component
struct CustomAlert {
@Consume('panelHeight') panelHeight: string;
@Consume('zIndexd') zIndexd: number;
build() {
Column() {
}
.width("100%")
.height("100%")
.borderRadius({ topLeft: 15, topRight: 15 })
.backgroundColor(Color.Pink)
}
}
更多关于HarmonyOS 鸿蒙Next中模态转场如何实现上拉/下拉到固定高度后,不再跟手滑动,像华为地图/高德地图首页的那种效果?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在鸿蒙Next中实现模态转场固定高度效果,需使用SheetModal组件并设置detent属性。通过SheetDetent指定固定高度值,当拖拽达到该阈值时模态框将锁定位置不再跟随手势移动。具体实现时需定义SheetPresentationMode为SHEET模式,并在detent中配置目标高度参数。该机制与地图应用的下拉悬停交互原理一致。
在HarmonyOS Next中实现模态转场在固定高度停止跟手滑动,可以通过以下方式实现:
- 使用
SheetPresentation设置detent属性:
sheetPresentation.detent = Detent.MEDIUM; // 设置停靠高度为中等
sheetPresentation.presentationDetents = [Detent.MEDIUM]; // 限制停靠点
- 配置交互行为:
sheetPresentation.interactionDisabled = true; // 禁用交互拖动
// 或者
sheetPresentation.draggable = false; // 禁止拖动
- 自定义模态组件时,在
aboutToAppear中设置:
aboutToAppear() {
this.sheetPresenter.setDetents([Detent.MEDIUM]);
this.sheetPresenter.setDraggable(false);
}
- 对于地图类应用的特殊处理:
// 设置停靠点为固定值
sheetPresentation.presentationDetents = [Detent.LARGE];
sheetPresentation.selectedDetent = Detent.LARGE;
关键是通过detent控制停靠位置,结合draggable或interactionDisabled属性来限制用户拖动。这种实现方式与华为地图的交互效果一致,模态窗口会在指定高度停靠后固定位置。

