【问题标题】:x and y in a MotionEvent ACTION_UP is sometimes duplicate of an earlier ACTION_MOVEMotionEvent ACTION_UP 中的 x 和 y 有时与之前的 ACTION_MOVE 重复
【发布时间】:2021-06-06 09:53:32
【问题描述】:

亲爱的花友们,

问题描述

我正在使用来自 onTouchEvent(event: MotionEvent) 的输入绘制一个简单的视图。为了实现这一点,我使用 ACTION_DOWN、ACTION_MOVE 和 ACTION_UP 中的坐标和一个指针。

除了每个 MotionEvent 的 x 和 y 值之外,我还对历史 x 和 y 感兴趣,以获取尽可能多的数据。问题是 ACTION_UP 事件中的 x 和 y 通常与前一个 ACTION_MOVE 的最后一个相同

问题示例

让我用 4 个 MotionEvents 的示例来说明用户触摸屏幕,稍微移动手指然后松开手指。在示例中,我将 xHistory 用于可通过 getHistoricalX 获得的值列表,并使用 yHistory 与 getHistoricalY 相同。

1. ACTION_DOWN:

  • xHistory = []
  • yHistory = []
  • x = 5.0
  • y = 6.0

2。 ACTION_MOVE:

  • xHistory = [5.5, 5.8, 6.2]
  • yHistory = [6.5, 6.8, 7.2]
  • x = 6.6
  • y = 7.6

3. ACTION_MOVE:

  • xHistory = [7.0, 7.5, 8.0]
  • yHistory = [7.7, 7.8, 8.0]
  • x = 8.5
  • y = 8.2

4. ACTION_UP:

  • xHistory = []
  • yHistory = []
  • x = 8.0
  • y = 8.0

在第四个事件中可以看出,ACTION_UP的x和y与xHistory和yHistory的最后一个索引相同。即使我没有向后移动手指,也会发生这种情况。我希望 ACTION_UP 的 x 和 y 始终与最后一个 ACTION_MOVE 事件的 x 和 y 相同(如果有的话)。

实施

我使用 MotionEvent.getHistoricalX() 和 MotionEvent.getHistoricalY() 结合 MotionEvent.x 和 MotionEvent.y 在 MotionEvent 的扩展属性 (kotlin) 中构建点列表。

在实现中,我创建了一个点列表,其中的点由大小为 2 的 FloatArrays 表示。我将包含历史坐标和最新坐标的列表称为 historyVector

val MotionEvent.historyVector: Array<FloatArray>
    get() {
        val historyVector = mutableListOf<FloatArray>()

        for (i in 0 until this.historySize) {
            historyVector.add(floatArrayOf(this.getHistoricalX(i), this.getHistoricalY(i)))
        }
        historyVector.add(floatArrayOf(this.x, this.y))

        return historyVector.toTypedArray()
    }

我将这个 historyVector 用于 ACTION_DOWN、ACTION_MOVE 和 ACTION_UP,有时结果符合预期,有时结果与上一节中的示例类似。

你们中有人见过这种行为吗?我认为一定有什么我误解了和/或我做错了什么。

【问题讨论】:

  • 您使用的是物理设备还是模拟器?我想我在模拟器上遇到过这种情况,但在真实设备上却没有(抛出失败或被逆转等)
  • 物理设备。运行 Android 10 的诺基亚 4.2

标签: android motionevent


【解决方案1】:

我以前从未见过这种行为,但是您可以执行以下操作之一:

  • 在最新的 ACTION_MOVE 坐标中考虑 ACTION_UP(额外的检查可能是检查毫秒差异,并且仅当此差异小于 100 毫秒时才假定最新的 Move 坐标)
  • 当 ACTION_UP 发生时,您可以使用 UP 的坐标“创建/引发虚假”ACTION_MOVE 事件

此外,您还可以检查 ACTION_UP.getEventTimeNano() 并验证此事件是否真的在上次 ACTION_MOVE.getEventTimeNano() 之后发生,如果不是,则丢弃其信息并仅使用 ACTION_MOVE 数据。

【讨论】:

  • 感谢您的建议。我正在考虑将 ACTION_UP 视为我当前正在绘制的笔画的终点并忽略它的坐标,但担心如果那里确实有一些新数据,这有时可能是错误的
猜你喜欢
  • 2013-10-22
  • 1970-01-01
  • 2011-07-11
  • 2021-09-11
  • 1970-01-01
  • 2022-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多