2010-11-19 11 views
8

Así que estoy desarrollando una aplicación que debe manejar multitouch. Básicamente quiero un solo toque para rotar (esto no es problema). Y multitáctil para desplazarse.Cómo codificar para multitouch

Tengo el código básico, pero estoy teniendo problemas cuando ocurre el cambio de single a multitouch y vice verca. Básicamente, el movimiento se sacudirá porque la posición media del multitouch (dos dedos) y la posición absoluta del dedo se encuentran a una distancia. Entonces, si tengo dos dedos en la pantalla, ellos hacen una posición mediana, y luego levantan un dedo, sería como un movimiento rápido desde esa posición mediana hasta la posición de dedo único absoluto. Este será el movimiento que no quiero.

Este es mi código:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    float xEvent[] = new float[ 2 ]; 
    float yEvent[] = new float[ 2 ]; 
    switch(event.getPointerCount()) { 
     case 1: 
      xEvent[ 0 ] = event.getX(0); 
      yEvent[ 0 ] = event.getY(0); 
      switch(event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        camera.onTouchDown(xEvent[ 0 ], yEvent[ 0 ]); 
        return true; 
       case MotionEvent.ACTION_MOVE: 
        camera.onTouchRotate(xEvent[ 0 ], yEvent[ 0 ]); 
        return true; 
       default: return super.onTouchEvent(event); 
      } 
     case 2: 
      xEvent[ 0 ] = event.getX(0); 
      yEvent[ 0 ] = event.getY(0); 
      xEvent[ 1 ] = event.getX(1); 
      yEvent[ 1 ] = event.getY(1); 
      switch(event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        camera.onTouchDown(((xEvent[ 0 ] + xEvent[ 1 ])/2), ((yEvent[ 0 ] + yEvent[ 1 ])/2)); 
        return true; 
       case MotionEvent.ACTION_MOVE: 
        camera.onTouchSlide(((xEvent[ 0 ] + xEvent[ 1 ])/2), ((yEvent[ 0 ] + yEvent[ 1 ])/2)); 
        return true; 
       case MotionEvent.ACTION_POINTER_1_UP: 
        camera.onTouchDown(xEvent[ 1 ], yEvent[ 1 ]); 
        return true; 
       case MotionEvent.ACTION_POINTER_2_UP: 
        camera.onTouchDown(xEvent[ 0 ], yEvent[ 0 ]); 
        return true; 
       default: return super.onTouchEvent(event); 
      } 
     default: return false; 
    } 
} 

La función onTouchDown de la cámara justo establece el primer valor del movimiento táctil. Es por eso que también lo uso en el movimiento ascendente para establecer un nuevo valor de inicio para el movimiento de un solo toque cuando proviene de un multitouch.

Espero que alguien sepa cuál es mi problema y me puede ayudar más.

Respuesta

10

Comienza aquí si no lo ha leído ya, no hace falta más de un número de cosas que se ocupan de multitouch en Android: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html

algunas cosas acerca de su código publicado:

  1. podrás nunca vea ACTION_DOWN con un conteo de puntero de 2. ACTION_DOWN solo se envía para el primer puntero que baja. Todos los dedos que toquen la pantalla después de la primera enviarán ACTION_POINTER_DOWN.
  2. No asuma que solo toque con dos dedos, puede haber más fácilmente.
  3. Es mucho más fácil trabajar con la acción enmascarada (use MotionEvent#getActionMasked()) que codificar individualmente para cada índice de puntero.
  4. Al final, los índices solo importan para extraer datos de un MotionEvent. Si está rastreando el movimiento del puntero a lo largo del tiempo, use la ID del puntero.
  5. Los identificadores de puntero son solo números. No haga suposiciones sobre qué valores tendrán, sino que serán enteros desde 0 en adelante.
+0

Gracias! Acabo de terminar una implementación que funciona al 80%. Pero después de leer ese enlace, creo que puedo hacerlo mejor usando máscaras e identificadores. – Espen

2

Puede resolver esto con operaciones matemáticas sencillas, aunque puede haber una mejor manera ya incorporado.

Basta con crear un objeto que mantiene la posición de cada dedo cuando se activa el evento .ACTION_POINTER_X_UP y un objeto booleano que mantiene qué tipo de modo táctil utilizaste por última vez.

case MotionEvent.ACTION_POINTER_1_UP: 
     camera.onTouchDown(xEvent[ 1 ], yEvent[ 1 ]); 
     boolean usedMultiTouch = true; 
     int x = event.getX(1); 
     int y = event.getY(1); 
     return true; 

Siguiente su ACTION_MOVE (dentro de la caja = 1) Declaración se disparará cuando el usuario mueve su dedo mientras ellos se iban de múltiples a un solo toque.

Ahora, dependiendo de lo que quiere hacer, puede ignorar el solo movimiento (el booleano es su cheque) hasta que se activa el evento .ACTION_UP y se establece el booleano de nuevo a falsa

o

usted llama a un método que hace algunos cálculos basados ​​en los valores de ubicación guardados y el dedo que aún está en la pantalla. Las matemáticas deberían ser bastante fáciles, pero no sé lo que realmente quieres hacer.

Cuestiones relacionadas