2016-09-19 93 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超出範圍。

將更徹底地解釋如果沒有意義,如果有人有一個更優雅的解決方案,請讓我知道,因爲我相信這不是一個好辦法來處理這個問題。我寧願將其他人的答案標記爲批准的答案。