HarmonyOS 如何实现悬浮按钮?

在页面覆盖一个悬浮按钮 按钮可以随意拖动 点击 控制显示隐藏

阅读 434
1 个回答

可以参考以下demo:

import {  window } from '@kit.ArkUI'

@Entry
@Component
struct SuspensionButton {
  @State statusHeight: number = 0 //状态栏高度
  @State bottomAvoidAreaHeight: number = 0 //手机底部规避区域高度
  @State curLeft: number = 0 //当前悬浮按钮距离窗口左边距离
  @State curTop: number = 0 //当前悬浮按钮距离窗口顶部距离
  private startLeft: number = 0 //开始移动那一刻悬浮按钮距离窗口左边距离
  private startTop: number = 0 //开始移动那一刻悬浮按钮距离窗口顶部距离
  private startX: number = 0 //开始移动触摸点x坐标,相对窗口左上角
  private startY: number = 0 //开始移动触摸点y坐标,相对窗口左上角
  private radius: number = 25 //悬浮按钮半径,单位vp
  private winWidth: number = 0 //窗口宽度
  private winHeight: number = 0 //窗口高度
  @State num:number = 0;

  aboutToAppear() {
    this.getWindowInfo()

  }

  //获取窗口尺寸信息
  getWindowInfo() {
    window.getLastWindow(getContext(this), (err, windowClass) => {
      if (!err.code) {
        //状态栏高度
        this.statusHeight = px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height)
        //获取手机底部规避区域高度
        this.bottomAvoidAreaHeight = px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR)
          .bottomRect
          .height)

        //获取窗口宽高
        let windowProperties = windowClass.getWindowProperties()
        this.winWidth = px2vp(windowProperties.windowRect.width)
        this.winHeight = px2vp(windowProperties.windowRect.height)

        //设置初始位置位于屏幕右下角,演示设置可根据实际调整
        this.curLeft=this.winWidth*0.8
        this.curTop=this.winHeight*0.8
      }
    })
  }

  build() {

    Stack() {
      Column(){
        //页面内容

      }.width('100%').height('100%')

      //悬浮按钮
      if(this.num == 0){
        Column() {
          Image($r('app.media.xmark_circle')).width(15).position({ x: 50, y: 8 })
            .onTouch((event: TouchEvent) => {
              // parent.removeColumn(this)
              // parent.invalide()
              this.num = 1
            })
          Image($r('app.media.airplane_fill')).width(40)
        }
        .width(this.radius * 3)
        .height(this.radius * 3)
        .justifyContent(FlexAlign.Center)
        .borderRadius(this.radius)
        // .backgroundColor('white')
        .position({
          x: this.curLeft,
          y: this.curTop
        })
        .onTouch((event: TouchEvent) => {
          //手指按下记录初始触摸点坐标、悬浮按钮位置
          if (event.type === TouchType.Down) {
            this.startX = event.touches[0].windowX
            this.startY = event.touches[0].windowY
            this.startLeft = this.curLeft
            this.startTop = this.curTop
          }

          //手指拖动
          else if (event.type === TouchType.Move) {
            let touch = event.touches[0]

            //计算悬浮球与左边距离(x坐标), 当前悬浮球距离左边=开始位置(x轴)+(当前触摸点x坐标-开始移动触摸点x坐标)
            let curLeft = this.startLeft + (touch.windowX - this.startX)
            //限制悬浮球不能移除屏幕左边
            curLeft = Math.max(0, curLeft)
            //限制悬浮球不能移除屏幕右边
            this.curLeft = Math.min(this.winWidth - 2 * this.radius, curLeft)

            //计算悬浮球与顶部距离(y坐标), 当前悬浮球距离顶部=开始位置(y轴)+(当前触摸点y坐标-开始移动触摸点y坐标)
            let curTop = this.startTop + (touch.windowY - this.startY)
            //限制悬浮球不能移除屏幕上边
            curTop = Math.max(0, curTop)
            //限制悬浮球不能移除屏幕下边
            this.curTop = Math.min(this.winHeight - 2 * this.radius - this.bottomAvoidAreaHeight - this.statusHeight, curTop)
          }
        })}

    }.width('100%')
    .height('100%')
    .backgroundColor('#f2f2f2')

  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进