You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用悬浮按钮如何获取MotionEvent的真实触摸位置

解决Android悬浮按钮拖拽位置偏移问题

不用计算状态栏或导航栏高度,最优方案是记录触摸点相对于悬浮按钮的内部偏移量,通过相对移动来更新位置,完全规避系统栏对坐标的影响。

修改后的代码

val displayMetrics = displayData.getInstance()
cursorView = Button(context)
val cursorSize = displayMetrics.screenSizeX / 10
cursorView?.setBackgroundResource(R.drawable.cursor)
cursorParams = WindowManager.LayoutParams(
    cursorSize, cursorSize,
    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    PixelFormat.TRANSLUCENT
)
cursorParams?.gravity = Gravity.START or Gravity.TOP

cursorParams?.x = (displayMetrics.screenSizeX - cursorSize) / 2
cursorParams?.y = (displayMetrics.screenSizeY - cursorSize) / 2

// 记录触摸点相对于按钮的偏移量
var downX = 0f
var downY = 0f

cursorView?.setOnTouchListener { _, event ->
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {
            // 保存触摸点在按钮内的坐标(相对于按钮左上角)
            downX = event.x
            downY = event.y
            true
        }
        MotionEvent.ACTION_MOVE -> {
            // 用屏幕绝对坐标减去偏移量,得到按钮左上角的正确位置
            cursorParams?.x = (event.rawX - downX).toInt()
            cursorParams?.y = (event.rawY - downY).toInt()
            Tools.logMessage(message = "Screen Size: ${displayMetrics.screenSizeX} x ${displayMetrics.screenSizeY}")
            Tools.logMessage(message = "Calculated Cursor Position: ${cursorParams?.x}, ${cursorParams?.y}")

            windowManager.updateViewLayout(cursorView, cursorParams)
            true
        }
        else -> false
    }
}

windowManager.addView(cursorView, cursorParams)

关键逻辑说明

  1. ACTION_DOWN时记录偏移:当用户按下按钮时,用event.x和event.y获取触摸点相对于按钮自身左上角的坐标,这个偏移量是固定的(只要用户不改变触摸点在按钮上的位置)。
  2. ACTION_MOVE时计算新位置:用event.rawX/event.rawY(屏幕绝对坐标)减去之前记录的偏移量,直接得到按钮左上角应该在的屏幕绝对位置,完全不用考虑状态栏、导航栏的存在——因为rawX/rawY是屏幕物理坐标,偏移量是按钮内部的相对坐标,两者相减的结果就是按钮在屏幕上的准确位置。

这种方法的优势:

  • 适配所有Android设备,无需额外计算系统栏高度,避免因设备差异(如刘海屏、折叠屏)导致的适配问题。
  • 逻辑更简洁,直接通过相对移动实现精准拖拽,不会出现位置偏移。

内容的提问来源于stack exchange,提问作者Droid Automations

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 05:02:36