MultiToque Android | Acción de cada punto de contacto
Estoy tratando de manejar multiTouch en android, mi plan es usar 2 dedos en la aplicación. Sé cómo utilizar un punto de contacto, pero no estoy seguro acerca de cómo utilizar más de un punto de contacto.
Aquí está mi código, OnTouch:
- Detección de una larga pulsación con Android
- ¿Cómo utilizar ADB para enviar eventos táctiles al dispositivo utilizando comando sendevent?
- Problema con los descriptores HID de la pantalla táctil USB de Android
- Android Cómo dibujar una línea suave después de su dedo
- Disposición de superposición de Android encima de todas las ventanas que recibe toques
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; }
ahora después de obtener las coordenadas xey para cada punto, ¿cómo obtendría la acción que sucede? Quiero utilizar event.getAction
, pero no toma un parámetro como el índice de puntos. ¿cómo puedo obtener el tipo de acción para cada punto de contacto?
ACTUALIZACIÓN: ok, así que ahora puedo manejar y manejar con éxito dos dedos, ahora, después de haberlo hecho, hice una clase sencilla llamada Finger
para manejar cada punto de contacto, ahora cuando tengo dos dedos en la pantalla, e intento para eliminar uno de ellos, y luego mover / quitar el otro dedo, el juego sólo se bloquea!
En contacto:
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; }
creo una lista para los dedos:
List fingers = new LinkedList ();
en el constructor pongo:
fingers.add(0, null); fingers.add(1, null);
Finalmente, la Clase del Dedo:
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; } }
ahora cuando hago todo eso, todo está bien, hasta que quitar un dedo y mover / quitar el otro, me sale el siguiente error en el 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)
ACTUALIZAR:
en lugar de reajustar los dedos y ponerlos a nulo y luego volver a configurarlos de nuevo, acabo de eliminarlos cuando el dedo estaba arriba y volver a crearlos cuando el dedo estaba abajo y actualizado cuando el dedo se movió. Ahora funciona perfectamente bien!
ACTUALIZAR….
finalmente el problema no se resuelve, a pesar de que la aplicación no se bloquea, cuando uno de los dedos se levantó, actúa como si ambos dedos se levantó.
aquí está el código actual del método 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: } } }
por lo que cada vez que uno de los dedos se levanta, el logCat escribe como si ambos dedos fueron levantados de la pantalla. ¿algunas ideas?
- Determinar si el dispositivo tiene pantalla táctil o no
- Android: detecta mediante programación si el dispositivo tiene una pantalla táctil de hardware conectada
- No puede usar botones capacitivos mientras toca la pantalla
- Android, ayuda a girar la imagen en el tacto
- La función de desplazamiento fijo de la imagen de fondo en dispositivos móviles de toque no se actualiza inmediatamente
- Desplazar la columna de Gridview hacia arriba y hacia abajo al tocar esa columna
- ListView en SlidingDrawer pierde foco después de onResume
- Ajustar la frecuencia de muestreo de entrada táctil en Android
consulte, por ejemplo, las fuentes de ScaleGestureDetector cómo se realiza: https://android.googlesource.com/platform/frameworks/base/+/48c7c6c/core/java/android/view/ScaleGestureDetector.java
- Flickr Oauth Conectarse con Scribe Library
- Android IAP – ¿Dónde están los IAP almacenados en el dispositivo?