8 votes

Android multitouch: ACTION_UP n'est pas toujours appelé?

J'ai développé une application Android qui gère le multitouch dans une vue. Je suis essentiellement les différents MotionEvents qui peuvent se produire comme ACTION_UP, ACTION_MOVE, ... Ma méthode onTouch redéfinie dans la classe View ressemble à ceci :

public boolean onTouch(View view, MotionEvent event) 
{
    int action = event.getAction() & MotionEvent.ACTION_MASK;

    if (action == MotionEvent.ACTION_DOWN) {
        float x = event.getX();
        handleTouchStart(view, x);
    } else if (action == MotionEvent.ACTION_UP) {
        float x = event.getX();
        handleTouchEnded(view, x);
    } else if (action == MotionEvent.ACTION_POINTER_DOWN) {
        int pointer = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
        float x = event.getX(pointer);
        handleTouchStart(view, x);
    } else if (action == MotionEvent.ACTION_POINTER_UP) {
        int pointer = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
        float x = event.getX(pointer);
        handleTouchEnded(view, x);
    } else if (action == MotionEvent.ACTION_MOVE) {
        int pointer = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
        float x = event.getX(pointer);
        handleTouchMoved(view, x);
    }

    return true;
}

Sur mon téléphone (Samsung Galaxy S), cela fonctionne parfaitement. À chaque handleTouchStart(), le handleTouchEnded() approprié est appelé. C'est crucial pour mon application. C'est un jeu de plateforme 2D avec une zone de direction dans la partie inférieure gauche de l'écran. Si - pour une raison quelconque - la méthode handleTouchEnded() n'est pas appelée lorsque l'utilisateur lève un doigt de l'écran tactile, le personnage du joueur continue de courir.

J'ai reçu des rapports de joueurs sur d'autres appareils (comme le HTC Desire) indiquant que dans de rares occasions, le personnage continue en effet de courir dans une direction même s'ils ont retiré leur doigt de la zone de direction sur l'écran. J'en ai conclu que cela ne peut se produire que si handleTouchEnded() n'est pas appelé, ce qui signifie à son tour qu'aucun événement ACTION_UP (ou ACTION_POINTER_UP) n'est généré.

Y a-t-il des implémentations spécifiques aux appareils pour le support du multitouch? Peut-on garantir que pour chaque MotionEvent ACTION_DOWN (ou ACTION_POINTER_DOWN), un MotionEvent ACTION_UP (ou ACTION_POINTER_UP) approprié est appelé? Ou est-ce que je manque quelque chose? Mon implémentation de onTouch est-elle correcte?

Ma question plus large serait : y a-t-il de meilleures façons de gérer l'entrée tactile multitouch pour les jeux d'"action"? Je reproduis essentiellement les commandes gauche et droite d'une croix directionnelle de manette de jeu. J'ai constaté que les boutons de l'interface utilisateur d'Android n'offrent pas assez de flexibilité car ils ne peuvent pas suivre les événements onPress et onRelease... ou le peuvent-ils?

17voto

adamp Points 19097

Vous manquez quelque chose. ;) Il y a un autre type d'action que vous devriez gérer: ACTION_CANCEL. ACTION_CANCEL est envoyé lorsque le geste en cours est annulé à un niveau supérieur - un composant de niveau supérieur peut avoir intercepté le geste et l'avoir pris en charge, etc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X