2012-04-04 17 views
2

それで、単純に言えば、私がマルチタッチに使用していたハンドラがクラッシュし、「IllegalArgumentException:pointerIndexが範囲外です。Android:アンドロイドのマルチタッチアプリケーションのための適切なポインタIDの取得

私はちょうどエラーをキャッチしようとしましたが、(x、y)が(min.x、max.y)(デフォルトでは、私の場合は0.0,480.0)であることに気付きました。

スパムが発生している間にエラーが発生するだけですが、2つの異なる場所を交互にタップするだけで特定の、非常に定期的に再生される可能性があります通常のマルチタッチゲーム)。それは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本のコードで2本の指でこの問題を修正することができました。

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

私はこれが実際に問題を修正した場合はわからないが、タッチスクリーンFPSゲームのために使用されるもののような二本指のマルチタッチコントロールのための偉大な動作しているようです。 私自身のテストでは、例外なく両ポイントからのタッチを正確に判断でき、正しい(x、y)値を保存することができました。

もっと良い解決策がありますか、それは悪い? 誰かが知りたいのであれば、これは4.0.3デバイス上にあった。

+0

ご質問はありますか? – slayton

+0

この問題を解決する方法はありますか?同様に、私のコードに根本的な問題がありますか?または、これはすべてのマルチタッチコードのバグで、このような回避策のみが「修正」されていますか? – cavemaneca

答えて

0

event.getX()とevent.getY()に というpointerIdを引数として(ACTION_POINTER_DOWNで)アクセスすることは奇妙に思えます。 代わりに他のすべての場合と同様に、代わりにpointerIndexを指定する必要があると思います。

関連する問題