HarmonyOS 鸿蒙Next中长按弹出气泡

HarmonyOS 鸿蒙Next中长按弹出气泡 如何在页面任意位置长按时在手指长安的位置上方弹出气泡

7 回复

你好,使用 bindContextMenu 即可,不设置placement,菜单就会跟随长按位置弹出。

@Entry
@Component
struct Index {
  @Builder
  MenuBuilder() {
    Text('弹出菜单')
      .fontSize(20)
      .width(100)
      .height(50)
      .textAlign(TextAlign.Center)
  }

  build() {
    Column() {
      Text('长按弹出')
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
  }
}

更多关于HarmonyOS 鸿蒙Next中长按弹出气泡的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


请问为什么设置箭头后就不能在长按位置弹出了,而且弹出的位置只能在手指的右下角吗,如何更改?

那需要稍微自定义一下:

@Entry
@Component
struct Index {
  @State isShowPopup: boolean = true
  @State offsetX: number = 0
  @State offsetY: number = 0

  @Builder
  MenuBuilder() {
    Text('弹出菜单')
      .fontSize(20)
      .width(100)
      .height(50)
      .textAlign(TextAlign.Center)
  }

  build() {
    Stack() {
      Column() {
        Text('长按弹出')
      }
      .width('100%')
      .height('100%')
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .parallelGesture(
        GestureGroup(GestureMode.Exclusive,
          TapGesture()
            .onAction(() => {
              this.isShowPopup = false
            }),

          LongPressGesture()
            .onAction((event) => {
              const f = event.fingerList?.[0]
              if (f) {
                this.offsetX = f.localX
                this.offsetY = f.localY
                console.log(this.offsetX + '---', this.offsetY)
                this.isShowPopup = true
              }
            })
        )
      )

      Row()
        .width(1)
        .height(1)
        .visibility(this.isShowPopup ? Visibility.Visible : Visibility.Hidden)
        .bindPopup(true, {
          builder: this.MenuBuilder(),
          placement: Placement.Top
        })
        .offset({
          x: this.offsetX,
          y: this.offsetY
        })
    }
    .alignContent(Alignment.TopStart)
  }
}

大概的实现思路如下 →

1.手势捕获:

使用 LongPressGesture 监听长按事件,通过 GestureEvent 获取手指按下的 全局坐标(globalX和 globalY)。

2.动态定位:

根据坐标动态计算 Popup 的偏移量 offset,确保气泡出现在手指位置上方。

3.气泡控制:

通过状态变量控制 Popup 的显示/隐藏,并设置 showInSubWindow: true实现全局定位。

给组件添加bindPopup(应该叫这个),

在HarmonyOS Next中,长按弹出气泡功能主要通过BubbleContainer组件实现。该组件是PopupExtension的子类,用于在长按触发时显示一个包含自定义内容的悬浮气泡。开发者需在EntryAbility中注册BubbleContainer,并配置其布局与交互逻辑。气泡的显示位置、内容及样式均可通过代码自定义。此功能适用于需要快速操作或信息预览的场景,如文本选择菜单、快捷工具提示等。

在HarmonyOS Next中,可以通过@ohos.ui框架的Popup组件配合手势事件来实现长按弹出气泡。核心步骤如下:

  1. 监听长按手势:使用Gesture组件的LongPressGesture事件,其回调参数event(类型为GestureEvent)提供了手指按下的位置信息(event.xevent.y)。

  2. 计算弹出位置:将获取到的event.xevent.y作为气泡(Popup)的显示坐标。注意坐标系通常相对于窗口或父组件,需根据实际布局调整。

  3. 创建并显示气泡:在长按事件的回调函数中,动态创建Popup组件,设置其alignmentAlignment.TopStart(或其他对齐方式),并通过offset属性结合长按坐标进行精确定位。然后调用show()方法弹出。

示例代码片段

import { popup } from '@kit.ArkUI';

// 在长按手势回调中
LongPressGesture({ repeat: false })
  .onAction((event: GestureEvent) => {
    // 创建Popup
    let popupController = popup.build();
    popupController.setAlignment(Alignment.TopStart);
    popupController.setOffset({ dx: event.x, dy: event.y - 100 }); // dy调整气泡在位置上方的偏移
    popupController.setContent(/* 气泡内容组件 */);
    popupController.show();
  })

关键点

  • 使用setOffset直接定位,避免依赖组件树布局。
  • 气泡内容需自定义,例如使用Column布局包含文本和操作按钮。
  • 可通过popupController.hide()关闭气泡,例如在气泡内添加关闭按钮。

此方法适用于在任意组件(如CanvasList项)上监听长按并精准弹出气泡。

回到顶部