web-dev-qa-db-fra.com

Désactiver ou empêcher le multitouch dans Activity

J'ai plusieurs vues sur une activité qu'un utilisateur veut toucher successivement et je capture ces touches en utilisant un TouchListener et en manipulant MotionEvent.ACTION_DOWN. Toutefois, si l'utilisateur utilise deux mains, il est fort probable que la vue suivante soit touchée avant que l'utilisateur ne lève le doigt précédent. Dans ce scénario, un MotionEvent.ACTION_MOVE est déclenché pour la première vue plutôt que le MotionEvent.ACTION_DOWN souhaité pour la deuxième vue.

Existe-t-il un moyen de contourner ou d'éviter ce comportement? J'ai essayé de distribuer un nouvel événement avec MotionEvent.ACTION_UP et de supprimer l'écouteur d'événements, mais aucun ne semble fonctionner.

25
cachance7

Le meilleur moyen de contourner ce scénario consiste à utiliser une variable ViewGroup et à implémenter la méthode onInterceptTouchEvent pour router manuellement les événements tactiles à votre guise. 

Cela a été répondu à l'origine ici: Android multitouch! pirater quelqu'un?

Le code implémentant cette solution (se trouvant dans la section commentaires de la réponse à la question ci-dessus) se trouve ici: http://Pastebin.com/hiE1aTCw

4
cachance7

Le moyen le plus simple que j'ai trouvé de forcer le contact unique sur une application entière est de la définir à l'aide d'un thème:

<style name="MyTheme" parent="@Android:style/Theme.Holo.Light">
    <item name="Android:windowEnableSplitTouch">false</item>
    <item name="Android:splitMotionEvents">false</item>
</style>

Manifeste:

  <application
        Android:label="@string/app_name"
        Android:theme="@style/MyTheme" >
65
Jeremie

si quelqu'un cherche toujours la meilleure solution, insère dans le code XML le code suivant:

Android:splitMotionEvents = false 
16
Oren Zakay

Je l'ai fait comme ça:

@Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub

    if(event.getPointerCount() > 1) {
        System.out.println("Multitouch detected!");
        return true;
    }
    else
        return super.onTouchEvent(event);
}

Je pense que vous pouvez remplacer onTouchEvent pour n’importe quelle vue.

8
Pijetren

J'ai résolu ce problème en utilisant une méthode personnalisée - ce que je ne voulais pas faire. Si quelqu'un trouve une meilleure solution, j'aimerais en entendre parler. Merci:

public static void setViewGroupEnebled(ViewGroup view, boolean enabled)
{
    int childern = view.getChildCount();

    for (int i = 0; i< childern ; i++)
    {
        View child = view.getChildAt(i);
        if (child instanceof ViewGroup)
        {
            setViewGroupEnebled((ViewGroup) child,enabled);
        }
        child.setEnabled(enabled);
    }
    view.setEnabled(enabled);
}
2
user647826

Ignore dispatchTouchEvent et intercepte toutes les touches, pour toutes les multi-touches, le nombre de points est supérieur à un.

 if(ev.getPointerCount() > 1)
  {
     Log.d("Multitouch detected!");
     ev.setAction(MotionEvent.ACTION_CANCEL);
  }

Ceci annule les effleurements et efface l'état enfoncé des boutons sans aucune autre action.

1
chetna priyadarshini
int currentapiVersion = Android.os.Build.VERSION.SDK_INT;

            if (currentapiVersion >= Android.os.Build.VERSION_CODES.HONEYCOMB) {

                horizentalLinearGridItem.setMotionEventSplittingEnabled(false);

            }

HorizentLinearGridItem est ici la vue parentLayout où nous insérons des vues enfant . Dans ce LinearLayout, j'ai ajouté des vues enfants. Mais lorsque j'ai cliqué simultanément sur deux vues enfants, les deux événements se produisaient. Pour bloquer que j'ai utilisé le code ci-dessus.

0
Abhijit Kurane

Je l'ai fait fonctionner pour moi en ajoutant simplement du code dans la méthode OnTouchEvent,

boolean action_down_required = false;

@Override
public boolean onTouchEvent(MotionEvent event) {

    int action = event.getAction();

    if(event.getPointerCount() > 1){
        action_down_required = true;
        return true;
    }

    if(action_down_required){
        action = MotionEvent.ACTION_DOWN;
    }

    switch (action) {
        case MotionEvent.ACTION_DOWN:

            // your code goes here...

            action_down_required = false;
            break;

        // Other events...
0
Amol Mejari