2012-04-04 4 views
2

간단히 말해서, 멀티 터치를 위해 사용하고 있던 핸들러가 충돌하여 "IllegalArgumentException : pointerIndex가 범위를 벗어났습니다."안드로이드 : 안드로이드의 멀티 터치 애플리케이션에 적합한 포인터 ID 가져 오기

오류를 잡으려고했지만 (x, y)가 (min.x, max.y)로 기본 설정된다는 것을 깨달았습니다. 제 경우에는 (0.0, 480.0)이었습니다.

스팸이 닿는 동안 오류가 발생하는 것을 알았지 만 두 개의 다른 장소에서 번갈아 가볍게 두드리기 만하면 특정 및 매우 규칙적으로 재생할 수있었습니다. 정규 멀티 터치 게임). 그것은 Log.d 출력에서 ​​무슨 일이 벌어지고 듯 무엇

public boolean onTouch(View v, MotionEvent event) { 
    synchronized (this) { 
     int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
     int pointerId = event.getPointerId(pointerIndex); 
     TouchEvent touchEvent; 

     // pointerId fix 
     if (pointerId >= event.getPointerCount() && pointerId > 0) 
      pointerId--; 

     switch (event.getAction() & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: 
     case MotionEvent.ACTION_POINTER_DOWN: 
      touchEvent = touchEventPool.newObject(); 
      touchEvent.type = TouchEvent.TOUCH_DOWN; 
      touchEvent.pointer = pointerId; 
      try { 
       touchEvent.x = touchX[pointerId] = (int) (event 
         .getX(pointerId) * scaleX); 
       touchEvent.y = touchY[pointerId] = (int) (event 
         .getY(pointerId) * scaleY); 
      } catch (IllegalArgumentException e) { 
       Log.d("multiTouchHandler", e.toString() + ":: PID = " 
         + pointerId); 
      } 
      isTouched[pointerId] = true; 
      touchEventsBuffer.add(touchEvent); 
      break; 

     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_POINTER_UP: 
      touchEvent = touchEventPool.newObject(); 
      touchEvent.type = TouchEvent.TOUCH_UP; 
      touchEvent.pointer = pointerId; 

      try { 
       touchEvent.x = touchX[pointerId] = (int) (event 
         .getX(pointerIndex) * scaleX); 
       touchEvent.y = touchY[pointerId] = (int) (event 
         .getY(pointerIndex) * scaleY); 
      } catch (IllegalArgumentException e) { 
       Log.d("multiTouchHandler", e.toString() + ":: PID = " 
         + pointerId); 
      } 
      isTouched[pointerId] = false; 
      touchEventsBuffer.add(touchEvent); 
      return false; 

     case MotionEvent.ACTION_MOVE: 
      int pointerCount = event.getPointerCount(); 
      for (int i = 0; i < pointerCount; i++) { 
       touchEvent = touchEventPool.newObject(); 
       touchEvent.type = TouchEvent.TOUCH_DRAGGED; 
       touchEvent.pointer = pointerId; 
       try { 
        touchEvent.x = touchX[pointerId] = (int) (event 
          .getX(pointerIndex) * scaleX); 
        touchEvent.y = touchY[pointerId] = (int) (event 
          .getY(pointerIndex) * scaleY); 
       } catch (IllegalArgumentException e) { 
        Log.d("multiTouchHandler", e.toString() + ":: PID = " 
          + pointerId); 
       } 
       isTouched[pointerId] = false; 
       touchEventsBuffer.add(touchEvent); 
      } 
      break; 
     case MotionEvent.ACTION_CANCEL: 
     } 
     return true; 
    } 
} 

가끔 pointerId 가능한 다음 포인터. (예 1)에 할당받을 것이라고했지만, 실제로 포인터 :

다음은 onTouch 방법입니다 데이터는 이전 포인터 위치 (0)에 저장됩니다.

pointerId가 현재 pointerCount의 범위를 벗어 났는지 확인하고 두 포인터가 2 줄의 코드로이 문제를 해결할 수있었습니다.

// pointerId fix 
if (pointerId >= event.getPointerCount() && pointerId > 0) 
       pointerId--; 

나는이 정말 문제가 해결되는지 모르겠지만, 터치 스크린 FPS 게임에 사용되는 것과 같은 두 손가락 멀티 터치 컨트롤 잘 작동하는 것 같다. 내 테스트에 따르면 예외없이 두 지점의 터치를 정확하게 파악하고 정확한 (x, y) 값을 저장할 수 있음을 보여주었습니다.

더 나은 해결책이 있는지 또는 멀티 터치 API에서 포인터 ID를 실제로 사용하고 있는지 나쁜? 누구나 알고 싶은 경우, 이것은 4.0.3 장치에서 발생했습니다.

+0

무엇이 당신의 질문입니까? – slayton

+0

이 문제를 해결하는 더 좋은 방법이 있습니까? 마찬가지로, 내 코드에 근본적인 문제가 있습니까? 아니면 모든 멀티 터치 코드의 버그로,이 "해결"과 같은 해결 방법 만 있습니까? – cavemaneca

답변

0

event.getX() 및 event.getY()에 pointerId를 (ACTION_POINTER_DOWN에서) 사용하여 액세스하는 것이 이상하게 보입니다. 다른 모든 경우보다 더 아래로 포인터를 대신 포인터가되어야한다고 생각합니다.

관련 문제