2010-11-19 20 views
8

Je suis donc en train de développer une application qui doit gérer le multitouch. Fondamentalement, je veux une seule touche pour la rotation (ce n'est pas un problème). Et multitouch pour le défilement.Comment coder pour le multitouch

J'ai le code de base, mais j'ai des problèmes quand le passage du simple au multitouch, et vice verca, se produisent. Fondamentalement, le mouvement va secouer parce que la position médiane du multitouch (deux doigts) et la position absolue de l'unique doigt sont à distance. Donc, si j'ai deux doigts sur l'écran, ils forment une position médiane, puis soulevez un doigt, ce serait comme un mouvement rapide de cette position médiane à la position absolue d'un seul doigt. Ce sera le mouvement que je ne veux pas.

Ceci est mon code:

@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 fonction OnTouchDown de l'appareil photo règle que la première valeur du mouvement touche. C'est pourquoi je l'utilise également dans le mouvement vers le haut pour définir une nouvelle valeur de départ pour le mouvement à simple pression en venant d'un multitouch.

J'espère que quelqu'un sait quel est mon problème et peut m'aider plus loin.

Répondre

10

Commencez ici si vous avez pas déjà lu, il va sur un certain nombre de choses traitant multitouch dans Android: http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html

Quelques choses à propos de votre code affiché:

  1. Vous aurez ne jamais voir ACTION_DOWN avec un nombre de pointeurs de 2. ACTION_DOWN est seulement envoyé pour le premier pointeur qui descend. Tous les doigts qui touchent l'écran après le premier enverra ACTION_POINTER_DOWN.
  2. Ne pas supposer que jusqu'à 2 doigts, il peut facilement être plus.
  3. Il est beaucoup plus facile de travailler avec l'action masquée (utilisez MotionEvent#getActionMasked()) que de coder individuellement pour chaque index de pointeur. En fin de compte, les indices ne sont importants que pour extraire des données d'un MotionEvent. Si vous suivez le mouvement du pointeur au cours du temps, utilisez l'ID du pointeur.
  4. Les ID de pointeur sont simplement des nombres. Ne faites pas d'hypothèses quant aux valeurs qu'ils auront à part qu'ils seront des entiers de 0 et plus.
+0

Thanx! Je viens de terminer une implémentation qui fonctionne à 80%. Mais après avoir lu ce lien, je pense que je peux faire mieux en utilisant des masques et des identifiants. – Espen

2

Vous pouvez résoudre ce avec les mathématiques simples, bien qu'il puisse y avoir une meilleure façon déjà construit.

Il suffit de créer un objet qui occupe la position de chaque doigt lorsque l'événement se déclenche .ACTION_POINTER_X_UP et un objet booléen qui détient quel type de TouchMode vous avez utilisé en dernier. déclaration

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; 

Suivant votre ACTION_MOVE (dans le cas = 1) se déclenche lorsque l'utilisateur déplace son doigt comme ils sont passés de plusieurs à toucher unique.

Maintenant, en fonction de ce que vous voulez faire, vous pouvez ignorer le seul mouvement (le booléen est votre chèque) jusqu'à ce que l'événement se déclenche .ACTION_UP et que vous définissez le booléen retour false

ou

vous appelez une méthode qui effectue des calculs basés sur les valeurs d'emplacement enregistrées et le doigt qui est toujours à l'écran. Les maths devraient être assez faciles, mais je ne sais pas ce que vous voulez vraiment faire.