问题描述
亲爱的 stackoverflowers,
问题描述
我正在使用来自 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 的 FloatArray
表示。我将包含历史坐标和最新坐标的列表称为 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,有时结果如预期,有时结果如上一节中的示例。
你们以前见过这种行为吗?我想一定是我误解了什么和/或我做错了什么。
解决方法
我以前从未见过这种行为,但是您可以执行以下操作之一:
- 在最新的 ACTION_MOVE 坐标处考虑 ACTION_UP(额外的检查可能是检查毫秒差异,并仅在此差异小于 100 毫秒时才假设最新的 Move 坐标)
- 当 ACTION_UP 发生时,您可以使用 UP 的坐标“创建/引发一个假的”ACTION_MOVE 事件
此外,您还可以检查 ACTION_UP.getEventTimeNano() 并验证此事件是否真的发生在最后一次 ACTION_MOVE.getEventTimeNano() 之后,如果不是,则丢弃其信息并仅使用 ACTION_MOVE 数据。