2013-03-09 1 views
4

Dans mon application Android, j'ai un ImageView où je voudrais que l'utilisateur puisse le lancer vers la gauche/droite/haut/bas pour changer l'image (cartes statiques) à l'adjacente. Mais en plus, j'aimerais avoir des capacités de zoom-pincement et une carte elle-même.Utiliser ScaleGestureDetector avec GestureDetector?

Je peux obtenir un zooming par pincement OU par pincement, mais pas ensemble. J'utilise GestureDetector (avec un SimpleOnGestureListener) pour le flinging. Et j'utilise ScaleGestureDetector (de Making Sense of Multitouch) pour la mise à l'échelle.

La difficulté est de déterminer quel écouteur de gestes invoquer lors d'une action tactile. C'est moins un problème de codage, mais un problème de logique. Sur une seule action tactile, est-ce une aventure ou une balance? Même lorsqu'un zoom pincé est utilisé, le MotionEvent initial est ACTION_DOWN. J'ai essayé d'utiliser la taille de l'image (intrinsèque ou mise à l'échelle?) Comme point de décision. Mais l'opération de mise à l'échelle initiale (lorsque la taille de l'image est intrinsèque et que je veux zoomer dessus) avec ACTION_DOWN semble m'échapper.

Quelqu'un a-t-il déjà abordé cette question avec succès?

Répondre

1

a finalement trouvé la réponse sur un lien: http://code.google.com/p/android/issues/detail?id=42591

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    boolean result = mScaleGestureDetector.onTouchEvent(event); 

    // result is always true here, so I need another way to check for a detected scaling gesture 
    boolean isScaling = result = mScaleGestureDetector.isInProgress(); 
    if (!isScaling) { 
     // if no scaling is performed check for other gestures (fling, long tab, etc.) 
     result = mCommonGestureDetector.onTouchEvent(event); 
    } 

    // some irrelevant checks... 

    return result ? result : super.onTouchEvent(event); 
} 
+0

bonne idée, mais ne fonctionne pas vraiment. Voir ma réponse – yonix

5

Vous pouvez passer les événements sur les deux détecteurs de geste.

Vérifiez http://developer.android.com/training/gestures/scale.html « Exemple de mise à l'échelle plus complexes »:

public boolean onTouchEvent(MotionEvent event) { 
    boolean retVal = mScaleGestureDetector.onTouchEvent(event); 
    retVal = mGestureDetector.onTouchEvent(event) || retVal; 
    return retVal || super.onTouchEvent(event); 
} 

Bien sûr, étant donné le bug Ratatat fait référence, super.onTouchEvent ne sera jamais appelé dans l'exemple ci-dessus, qui peut ou peut ne pas être très bien, en fonction de votre cas d'utilisation.

+1

J'ai essayé ceci et la réponse de Ratatat, et celui-ci a donné de meilleurs résultats pour moi. Lorsque vous manipulez le panoramique et le zoom simultanés, si vous utilisez cette réponse, vous pouvez gérer tout panoramique dans le rappel onScroll et tout zoom sur onScale, plutôt que d'essayer de faire un panoramique basé sur le mouvement dans focusX/focusY de l'action scale. –

0

L'idée de Ratatat's answer est OK, mais nous devons tout de même transmettre des événements à gestureDetector même si nous ne voulons pas faire de défilement, sinon il sera foiré.

J'ai fini avec quelque chose comme ceci:

scaleDetector = new ScaleGestureDetector(...); 

gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 
    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
     if (scaleDetector.isInProgress()) { 
      // don't allow scrolling while scaling 
      return false; 
     } 

     // handle scrolling 

     return true; 
    } 
} 

Et puis la mise en œuvre de » onTouchEvent devrait être comme dans aij's answer:

boolean result = scaleDetector.onTouchEvent(event); 
result = gestureDetector.onTouchEvent(event) || result; 
return result || super.onTouchEvent(event); 
Questions connexes