Android MotionEvent指针混乱

yun*_*yun 6 java android motionevent

我的Android应用程序存在问题,需要触摸跟踪事件(跟踪手指何时/何时向下移动,移动,向上等).我必须使用event.getX()event.getY()函数来获取当前触摸的坐标.

所以从过去几个月我学到的东西:

  • MotionEvent.ACTION_DOWN 跟踪第一次触地
  • MotionEvent.ACTION_POINTER_DOWN 跟踪后续触摸
  • MotionEvent.ACTION_UP 跟踪最后的修饰
  • MotionEvent.ACTION_POINTER_UP 跟踪上升的触摸
  • MotionEvent.ACTION_MOVE 跟踪任何触摸动作

在我的应用程序中,当我第一次触摸时,我遇到了一个重大问题.假设我有五个手指触摸我的设备(让我们称这些Touch 0,1,2,3,4).现在,当我举起Touch 0时,MotionEvent.ACTION_POINTER_UP是我得到的动作.完全可以理解; 我明白了 但是,现在这两件事情将会发生:

  • 从触摸1-4移动任何东西:IllegalArgumentException告诉我指针指数超出范围
  • 提起触摸1-4中的任何内容:向后扫描不同触摸的信息(event.getX()event.getY()会给我一个不同的手指信息)

我很想知道如何正确跟踪这些信息.有关如何正确跟踪信息或偏移触摸指针的任何线索?

我提供了我的代码的总体布局,但我觉得我没有做任何与众不同的事情(我确定它接近Android示例中的示例代码?):

@Override
public boolean onTouch(View v, MotionEvent event) {
    int action = event.getActionMasked();
    int ptr_idx = event.getPointerId(event.getActionIndex());

    try {
        switch (action) {
            case MotionEvent.ACTION_MOVE:
                handleActionPointerMove(event);
                break;

            // Order of touch downs doesn't matter to us
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN:
                handleActionPointerDown(event, ptr_idx); 
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                handleActionPointerUp(event, ptr_idx);
                break;
            }
        }
        catch (IllegalArgumentException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }
}

public void handleActionPointerMove(MotionEvent event) {
    for (int i = 0; i < event.getPointerCount(); i++) {
         handleInformation(event.getX(i), event.getY(i));
    }
}

public void handleActionPointerDown(MotionEvent event, int ptr_idx) {
    handleInformation(event.getX(ptr_idx), event.getY(ptr_idx));
}

public void handleActionPointerUp(MotionEvent event, int ptr_idx) {
    handleInformation(event.getX(ptr_idx), event.getY(ptr_idx));
}

public void handleInformation(int x, int y) {
    // Figures out what x+y means to us (are we in a certain box within the app? outside in clear zones? etc
}
Run Code Online (Sandbox Code Playgroud)

yun*_*yun 0

经过一晚上的思考后,我已经在打电话之前完成了这个MotionEvent.getX()工作MotionEvent.getY()

public int getAdjustment(int ptr_idx) {
    int adjust = 0; 
    for (int i = 0; i < event.getPointerCount(); i++) {
        // Get Actual Pointer Index of touch
        int adjustedPointerIndex = event.getPointerId(i);
        // If we've found the current touch's pointer index AND
        // the pointer index doesn't equal the sequential event's
        // pointers
        if ((adjustPointerIndex == ptr_idx) && (i != adjustPointerIndex)) {
            adjust = (adjustPointerIndex - i);
            break;
        }
    } 

    return adjust;
}

// Example Function using getAdjustment(int ptr_idx)
public void handleActionPointerUp(MotionEvent event, int ptr_idx) {
    int adjustment = ptr_idx - getAdjustment(ptr_idx);
    handleInformation(event.getX(adjustment), event.getY(adjustment));
}
Run Code Online (Sandbox Code Playgroud)

for循环语句的解释:

基本上,假设我们有 4 次触摸(触摸 0、1、2、3)。现在我们已经抬起了触摸 0,现在我们有了触摸 1、2、3。Android 会将这些触摸视为 0、1、2,实际指针索引为 1、2、3。为了获得正确的调整,我迭代了的MotionEvent指针(现在在 for 循环中是 0, 1, 2)。

现在,如果由于某种原因 Touch 0 或之间的任何触摸被删除,我们必须调整指针索引,并且getX()不了解getY()触摸的实际指针索引。即使我们有指针索引 1、2、3,它也只接受索引 0、1、2。因此,如果我们已经达到正确的当前触摸指针索引,但 的MotionEvent触摸索引不等于正确的触摸指针索引,我们通过做调整它adjust = adjustPointerIndex-i

ptr_idx完成此操作后,只需从我们正在分析的电流中减去它,我们就得到一个getX()可以getY()理解的值,而无需IllegalArgumentException指针索引超出范围。

如果这没有意义,我会更彻底地解释,如果有人有更优雅的解决方案,请告诉我,因为我确信这不是处理这个问题的好方法。我宁愿将其他人的答案标记为已批准的答案。