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.
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
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" >
si quelqu'un cherche toujours la meilleure solution, insère dans le code XML le code suivant:
Android:splitMotionEvents = false
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.
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);
}
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.
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.
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...