MultiTouch android | getting the action of each touch point

I am trying to handle multiTouch in android, my plan is to use 2 fingers in the application. I know how to use one touch point, but I'm not sure how to use more than one touch point.

Here is my code, 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; } 

Now that I get the x and y coordinates for each point, how would I get the action that happens? I want to use event.getAction , but does not accept a parameter like the index of a point. How can I get the type of action for each touch point?

UPDATE: So now I can successfully manage and process two fingers, now, after I have done this, I made a simple class called Finger to handle each touch point, now that I have two fingers on the screen, and I trying to remove one of them, and then move / remove the other finger, the game just crashes!

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

i create a finger list:

Finger list = new LinkedList ();

in the constructor, I put:

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

Finally, the Finger class:

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

Now when I do all this, everything is fine, until I remove one finger and move / delete the other, I get the following error in 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:

instead of reinstalling the fingers and setting them to zero and then setting them again, I simply deleted them when the finger was raised and re-created them when the finger was lowered and updated when moving the finger. Now it works great!

UPDATE ....

ultimately the problem is not resolved, although the application does not crash when one of the fingers rises, it acts as if both fingers are rising.

here is the current onTouch method 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: } } } 

therefore, whenever one of the fingers rises, logCat writes as if both fingers were taken off the screen. any ideas?

+4
source share
1 answer

Source: https://habr.com/ru/post/1481497/


All Articles