HarmonyOS鸿蒙Next中实现底部弹窗

HarmonyOS鸿蒙Next中实现底部弹窗

如何使用绝对正确的API顺序实现底部弹窗?

3 回复

使用场景

所有涉及到分享的场景

实现思路

第一步:管理弹窗状态,首先,在组件内定义一个 @State 布尔变量(如 isSheetOpen: boolean = false)来控制弹窗的显示和隐藏。

第二步:创建弹窗内容构建器,使用 @Builder 装饰器创建一个方法(如 sheetBuilder),这个方法将返回弹窗内部的UI组件树。这个 @Builder 方法可以包含任意的UI布局,如 Column、Row、List、Button 等,并且可以拥有自己的状态和逻辑。

第三步:绑定 bindSheet 到目标组件,选择一个宿主组件(通常是包含触发按钮的 Column 或整个页面 Stack),在这个宿主组件上,链式调用 .bindSheet() 方法。

第四步:触发弹窗显示,在UI中放置一个触发元素(如 Button)。在其 onClick 事件中,将 isSheetOpen 设置为 true,即可触发弹窗滑出。

第五步:实现弹窗内关闭逻辑,在 @Builder 构建的弹窗内容中,通常会有一个“取消”或“关闭”按钮。在这个按钮的 onClick 事件中,将 isSheetOpen 设置为 false,即可关闭弹窗。

实现效果

实现效果

完整实现代码

@Entry
@Component
struct SheetDemoPage {
  // 1. 定义状态变量,控制弹窗的显示与隐藏
  [@State](/user/State) isSheetOpen: boolean = false;
  [@State](/user/State) selectedOption: string = '尚未选择';

  build() {
    Column() {
      Text('bindSheet 演示')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 50, bottom: 40 })

      Text(`您选择的分享方式是: ${this.selectedOption}`)
        .fontSize(16)
        .fontColor('#666666')
        .margin({ bottom: 20 })

      // 4. 触发弹窗显示的按钮
      Button('分享内容')
        .fontSize(18)
        .onClick(() => {
          this.isSheetOpen = true; // 修改状态,触发弹窗
        })

      Blank()
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    // 3. 使用绝对正确的参数顺序绑定 bindSheet
    .bindSheet(this.isSheetOpen, this.sheetBuilder, {
      dragBar: true, // 显示顶部的拖拽条
    })
  }

  // 2. 创建弹窗内容的 [@Builder](/user/Builder)
  [@Builder](/user/Builder)
  sheetBuilder() {
    Column() {
      Text('分享到')
        .fontSize(20)
        .fontWeight(FontWeight.Medium)
        .margin({ top: 12, bottom: 20 })

      Grid() {
        GridItem() {
          this.ShareOptionItem('微信', $r('app.media.startIcon'))
        }
        GridItem() {
          this.ShareOptionItem('朋友圈', $r('app.media.startIcon'))
        }
        GridItem() {
          this.ShareOptionItem('微博', $r('app.media.startIcon'))
        }
        GridItem() {
          this.ShareOptionItem('QQ', $r('app.media.startIcon'))
        }
      }
      .columnsTemplate('1fr 1fr 1fr 1fr')
      .rowsGap(20)
      .columnsGap(10)
      .padding({ left: 16, right: 16 })
      .height(160)

      Divider().color('#E5E5E5').margin({ top: 20, bottom: 20 })

      // 5. 实现弹窗内的关闭逻辑
      Button('取消')
        .width('100%')
        .height(50)
        .fontSize(18)
        .fontColor('#007DFF')
        .backgroundColor(Color.Transparent)
        .onClick(() => {
          this.isSheetOpen = false; // 关闭弹窗
        })
    }
    .width('100%')
    .backgroundColor(Color.White)
    .borderRadius({ topLeft: 16, topRight: 16 })
  }

  // 用于构建单个分享选项的子组件
  [@Builder](/user/Builder)
  ShareOptionItem(title: string, icon: Resource) {
    Column({ space: 8 }) {
      Image(icon)
        .width(40)
        .height(40)
      Text(title)
        .fontSize(14)
        .fontColor('#333333')
    }
    .onClick(() => {
      this.selectedOption = title;
      this.isSheetOpen = false; // 选择后关闭弹窗
    })
  }
}

更多关于HarmonyOS鸿蒙Next中实现底部弹窗的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,实现底部弹窗主要使用@ohos.promptAction模块的showActionMenu方法。该方法可创建从屏幕底部弹出的菜单列表。基本步骤包括:导入模块,定义菜单项数组,调用showActionMenu并传入菜单配置参数(如titlebuttons等)。弹窗样式和行为(如菜单项文本、点击事件)通过配置对象控制。这是ArkTS的官方标准实现方式。

在HarmonyOS Next中,实现底部弹窗(通常指类似ActionSheet或模态底部弹窗)的正确方式是使用@CustomDialog装饰器创建自定义弹窗,并控制其从底部弹出动画。以下是关键API使用顺序和核心步骤:

  1. 定义弹窗组件:使用@CustomDialog装饰器定义一个自定义弹窗组件,在build方法中布局内容。
  2. 设置弹窗样式:通过CustomDialogControlleralignment属性设置为DialogAlignment.Bottom,使弹窗底部对齐。
  3. 控制显示与隐藏:调用controller.open()controller.close()方法,系统会自动处理底部弹出动画。

示例代码框架

// 1. 定义带装饰器的弹窗组件
@CustomDialog
struct BottomDialog {
  private controller: CustomDialogController

  // 2. 在构造函数中配置控制器,关键:alignment设置为Bottom
  constructor() {
    this.controller = new CustomDialogController({
      builder: this,
      alignment: DialogAlignment.Bottom, // 底部对齐
      customStyle: true // 启用自定义样式
    })
  }

  build() {
    // 3. 构建弹窗内容
    Column() {
      // 你的弹窗内容布局
    }
    .width('100%')
    .backgroundColor(Color.White)
    .borderRadius({ topLeft: 16, topRight: 16 })
  }
}

// 在使用页面中
struct Index {
  private dialogController: CustomDialogController = new CustomDialogController({
    builder: BottomDialog(),
    alignment: DialogAlignment.Bottom
  })

  build() {
    Button('显示底部弹窗')
      .onClick(() => {
        this.dialogController.open() // 正确调用顺序:先配置后打开
      })
  }
}

关键顺序要点

  • 必须先创建和配置CustomDialogController(指定alignment: DialogAlignment.Bottom
  • 再调用open()方法触发显示
  • 弹窗内容容器建议设置顶部圆角以符合底部弹窗视觉规范
  • 关闭使用close()方法,无需手动管理动画

注意事项

  • 确保弹窗宽度设置为100%以适配屏幕宽度
  • 背景色和圆角需自定义设置
  • 避免在弹窗配置完成前调用显示方法

这种实现方式直接使用HarmonyOS Next的标准弹窗能力,动画和交互行为由系统统一保障,无需手动编写动画曲线。

回到顶部