2016-09-19 129 views
5

我的Android应用程序出现问题,需要触摸跟踪事件(跟踪何时/何处手指滑落,移动,向上等)。我必须使用event.getX()event.getY()函数来获取当前触摸的坐标。Android MotionEvent指针索引混淆

所以从我在过去的几个月中已经了解到:

  • MotionEvent.ACTION_DOWN跟踪第一触摸下来
  • MotionEvent.ACTION_POINTER_DOWN轨道随后触地
  • MotionEvent.ACTION_UP跟踪最后的润色
  • MotionEvent.ACTION_POINTER_UP跟踪触摸动作
  • MotionEvent.ACTION_MOVE跟踪任何触摸动作

在我的应用程序中,当我的第一次触摸升起时,遇到了一个重大问题。比方说,我有五个手指触摸我的设备(让我们打电话给这些触摸0,1,2,3,4)。现在,当我抬起触摸0时,MotionEvent.ACTION_POINTER_UP是我得到的动作。完全可以理解;我明白了。不过,现在这两件事情会发生:

  • 从移动倒是1-4任何内容:获取一个IllegalArgumentException告诉我pointerIndex超出范围
  • 提起从倒是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 
} 

回答

0

调用MotionEvent.getX()MotionEvent.getY()前思考了一个晚上,我得到它的工作,这样做之后好:

:for循环语句

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)); 
} 

说明

基本上,可以说我们有4个触摸(触摸0,1,2,3)。现在我们已经提升了Touch 0,现在我们有了Touch 1,2,3。Android将会看到这些触摸为0,1,2,实际的指针指数为1,2,3。为了获得正确的调整,我迭代MotionEvent的指针(现在在for循环中是0,1,2)。

现在,如果由于某种原因触摸0或其中任何触摸被取出,我们必须调整指针索引为getX()getY()不理解触摸的实际指针索引。即使我们有指针索引1,2,3,它也只占用索引0,1,2。因此,如果我们已经达到正确的当前触摸指针索引BUT,那么MotionEvent的触摸索引不等于正确的触摸指针索引,我们通过做adjust = adjustPointerIndex-i来调整它。

这样做之后,刚刚从我们分析当前ptr_idx减去它,我们得到一个值getX()getY()可以不IllegalArgumentException理解为pointerIndex超出范围。

将更彻底地解释如果没有意义,如果有人有一个更优雅的解决方案,请让我知道,因为我相信这不是一个好办法来处理这个问题。我宁愿将其他人的答案标记为批准的答案。