HarmonyOS 鸿蒙Next中模态转场如何实现上拉/下拉到固定高度后,不再跟手滑动,像华为地图/高德地图首页的那种效果?

HarmonyOS 鸿蒙Next中模态转场如何实现上拉/下拉到固定高度后,不再跟手滑动,像华为地图/高德地图首页的那种效果? 如何禁止半模态弹窗的跟手滑动功能

3 回复

【背景知识】

  • 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指定固定高度值,当拖拽达到该阈值时模态框将锁定位置不再跟随手势移动。具体实现时需定义SheetPresentationModeSHEET模式,并在detent中配置目标高度参数。该机制与地图应用的下拉悬停交互原理一致。

在HarmonyOS Next中实现模态转场在固定高度停止跟手滑动,可以通过以下方式实现:

  1. 使用SheetPresentation设置detent属性:
sheetPresentation.detent = Detent.MEDIUM; // 设置停靠高度为中等
sheetPresentation.presentationDetents = [Detent.MEDIUM]; // 限制停靠点
  1. 配置交互行为:
sheetPresentation.interactionDisabled = true; // 禁用交互拖动
// 或者
sheetPresentation.draggable = false; // 禁止拖动
  1. 自定义模态组件时,在aboutToAppear中设置:
aboutToAppear() {
  this.sheetPresenter.setDetents([Detent.MEDIUM]);
  this.sheetPresenter.setDraggable(false);
}
  1. 对于地图类应用的特殊处理:
// 设置停靠点为固定值
sheetPresentation.presentationDetents = [Detent.LARGE];
sheetPresentation.selectedDetent = Detent.LARGE;

关键是通过detent控制停靠位置,结合draggableinteractionDisabled属性来限制用户拖动。这种实现方式与华为地图的交互效果一致,模态窗口会在指定高度停靠后固定位置。

回到顶部