4

Я пытаюсь обрабатывать multiTouch в android, мой план состоит в том, чтобы использовать 2 пальца в приложении. Я знаю, как использовать одну точку касания, но я не уверен, как использовать несколько точек касания.multiTouch android | получение действия каждой точки касания

Вот мой код, OnTouch:

public boolean onTouch(View view, MotionEvent event) { 

     for(int i = 0; i < event.getPointerCount(); i++){ 

      float x = event.getX(i); 
      float y = event.getY(i); 

      // using the data here... 
      //.... 
     } 
    return true; 
} 

теперь после я получить координаты х и у каждой точки, как бы я получить действие, которое происходит? Я хочу использовать event.getAction, но он не принимает параметр, такой как индекс точки. как я могу получить тип действия для каждой точки касания?

UPDATE: нормально, так что теперь я могу успешно управлять и работать с двумя пальцами, то теперь, после того, как я сделал это, я сделал простой класс называется Finger для обработки каждого касания точки, теперь, когда у меня есть два пальца на экран, и я пытаюсь удалить один из них, а затем переместить/удалить другой палец, игра просто падает!

OnTouch:

public boolean onTouch(View view, MotionEvent event) { 

     int pointerCount = event.getPointerCount(); 

     if(pointerCount > 2){ 
      pointerCount = 2; 
      System.out.println("too many fingers!"); 
     } // since i want to handle only two fingers, every other finger will be ignored. 

     for (int i = 0; i < pointerCount; i++) { 

      float x = event.getX(i); 
      float y = event.getY(i); 

      int id = event.getPointerId(i); 
      int action = event.getActionMasked(); 
      int actionIndex = event.getActionIndex(); 

      if (action == MotionEvent.ACTION_DOWN 
        || action == MotionEvent.ACTION_POINTER_DOWN) { 

       if (fingers.get(i) == null) 
        fingers.set(i, new Finger(x, y, id)); 


      } 

      if (fingers.get(i).type == Finger.SCREEN_FINGER) { 

       switch (action) { 
       case MotionEvent.ACTION_UP: 
        fingers.set(i, null); 
        System.out.println(id + " action_up!"); 
        break; 
       case MotionEvent.ACTION_POINTER_UP: 
        fingers.set(i, null); 
        System.out.println(id + " pointer_up!"); 
        break; 
       case MotionEvent.ACTION_MOVE: 
        fingers.get(i).setPos(x, y); 
        System.out.println(id + " action_move!, x: "+fingers.get(i).x+", y: "+fingers.get(i).y); 
        break; 
       default: 

       } 
      }else if (fingers.get(i).type == Finger.DPAD_FINGER) { 
       switch (action) { 
       case MotionEvent.ACTION_UP: 
        fingers.set(i, null); 
        System.out.println(id + " action_up! - dpad"); 
        break; 
       case MotionEvent.ACTION_POINTER_UP: 
        fingers.set(i, null); 
        System.out.println(id + " pointer_up! - dpad"); 
        break; 
       case MotionEvent.ACTION_MOVE: 
        fingers.get(i).setPos(x, y); 
        System.out.println(id + " action_move! - dpad, x: "+fingers.get(i).x+", y: "+fingers.get(i).y); 
        break; 
       default: 

       } 
      } 
     } 


     return true; 
    } 

создать список для пальцев:

Список пальцы = новый LinkedList();

в конструкторе я поставил:

fingers.add(0, null); 
fingers.add(1, null); 

Наконец, Finger Класс:

public class Finger { 
public final static int DPAD_FINGER = 0; 
public final static int SCREEN_FINGER = 1; 

public float x, y; 
public int type; 
public int id; 

public Finger(float x, float y,int id) { 
    this.id = id; 
    checkType(x, y); 
} 

public void checkType(float x, float y) { 
    if(x>Dpad.x && x < Dpad.x+Dpad.Width && y> Dpad.y && y<Dpad.y+Dpad.Height){ 
     System.out.println("inside DPAD"); 
     type = DPAD_FINGER; 
    }else{ 
     System.out.println("Outside DPAD"); 
     type = SCREEN_FINGER; 
    } 

} 

public void setPos(float x, float y){ 
    this.x = x; 
    this.y = y; 
} 



} 

теперь, когда я делаю все, что все нормально, пока я не удалить один палец и переместить/удалить другой один, я получаю следующее сообщение об ошибке в LogCat:

05-18 15:22:03.812: E/InputEventReceiver(20124): Exception dispatching input event. 
05-18 15:22:03.812: W/dalvikvm(20124): threadid=1: thread exiting with uncaught exception (group=0x41e00438) 
05-18 15:22:03.822: E/AndroidRuntime(20124): FATAL EXCEPTION: main 
05-18 15:22:03.822: E/AndroidRuntime(20124): java.lang.NullPointerException 
05-18 15:22:03.822: E/AndroidRuntime(20124): at smellychiz.projects.ogc.util.ChizView$1.onTouch(ChizView.java:70) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.View.dispatchTouchEvent(View.java:7241) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2185) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1928) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2116) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1469) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.app.Activity.dispatchTouchEvent(Activity.java:2477) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2064) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.View.dispatchPointerEvent(View.java:7430) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3457) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3389) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4483) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4461) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4565) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4533) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4584) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.Choreographer.doCallbacks(Choreographer.java:555) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.Choreographer.doFrame(Choreographer.java:523) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.os.Handler.handleCallback(Handler.java:615) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.os.Handler.dispatchMessage(Handler.java:92) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.os.Looper.loop(Looper.java:137) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at android.app.ActivityThread.main(ActivityThread.java:4950) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at java.lang.reflect.Method.invokeNative(Native Method) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at java.lang.reflect.Method.invoke(Method.java:511) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771) 
05-18 15:22:03.822: E/AndroidRuntime(20124): at dalvik.system.NativeStart.main(Native Method) 

UPDATE:

вместо того, чтобы переустанавливать пальцы и устанавливать их на нуль, а затем снова устанавливать их снова, я просто удалил их, когда был поднят палец, и повторно создал их, когда палец был опущен и обновлен при перемещении пальца. Теперь он отлично работает!

UPDATE ....

в конце концов, проблема не решена, даже если приложение не ломается, когда один из пальцев получить рассеялся, он действует, как если бы оба пальца получить снят.

здесь текущий код onTouch метода:

public boolean onTouch(View view, MotionEvent event) { 

    int pointerCount = event.getPointerCount(); 

    if(pointerCount > 2){ 
     pointerCount = 2; 
     System.out.println("too many fingers!"); 
    } // since i want to handle only two fingers, every other finger will be ignored. 

    for (int i = 0; i < pointerCount; i++) { 

     float x = event.getX(i); 
     float y = event.getY(i); 

     int id = event.getPointerId(i); 
     int action = event.getActionMasked(); 
     int actionIndex = event.getActionIndex(); 

     if (action == MotionEvent.ACTION_DOWN 
       || action == MotionEvent.ACTION_POINTER_DOWN) { 

      if (fingers.get(i) == null) 
       fingers.add(i, new Finger(x, y, id)); 


     } 

     if (fingers.get(i).type == Finger.SCREEN_FINGER) { 

      switch (action) { 
      case MotionEvent.ACTION_UP: 
       fingers.remove(i); 
       System.out.println(id + " action_up!"); 
       break; 
      case MotionEvent.ACTION_POINTER_UP: 
       fingers.remove(i); 
       System.out.println(id + " pointer_up!"); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       fingers.get(i).setPos(x, y); 
       System.out.println(id + " action_move!, x: "+fingers.get(i).x+", y: "+fingers.get(i).y); 
       break; 
      default: 

      } 
     }else if (fingers.get(i).type == Finger.DPAD_FINGER) { 
      switch (action) { 
      case MotionEvent.ACTION_UP: 
       fingers.remove(i); 
       System.out.println(id + " action_up! - dpad"); 
       break; 
      case MotionEvent.ACTION_POINTER_UP: 
       fingers.remove(i); 
       System.out.println(id + " pointer_up! - dpad"); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       fingers.get(i).setPos(x, y); 
       System.out.println(id + " action_move! - dpad, x: "+fingers.get(i).x+", y: "+fingers.get(i).y); 
       break; 
      default: 

      } 
     } 
    } 

так всякий раз, когда один из пальцев получить отменены, LogCat пишет, как будто, как пальцы были сняты с экрана. есть идеи?

ответ

0

см, например, источники ScaleGestureDetector, как это делаются: https://android.googlesource.com/platform/frameworks/base/+/48c7c6c/core/java/android/view/ScaleGestureDetector.java

+0

нормально, так что я могу успешно обрабатывать два точки касания, поэтому я сделал простой класс с именем 'Finger' для обработки каждой точки с идентификатором и отслеживать координаты x и y. теперь у меня проблема, когда у меня есть два пальца на экране, и я пытаюсь удалить один из них, а затем я перемещаю/удаляю другой палец, приложение просто сработает! Я выложу свой код в вопросе. – Baruch

+0

, пожалуйста, посмотрите последнее обновление. Буду признателен за любую помощь. Спасибо. – Baruch

+0

Что говорит logcat? – pskink

Смежные вопросы