2015-12-26 1 views
0

J'observe un comportement très étrange dans ListView avec la gestion de MotionEvent. J'ai sous-classé ListView afin d'ajouter des journaux. Voici ma sous-classe.Android - flux étrange de MotionEvent dans listview

public class MyListView extends ListView{ 
public MyListView(Context context) { 
    this(context, null); 
} 

public MyListView(Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
} 

public MyListView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 

@Override 
public boolean dispatchTouchEvent(MotionEvent ev){ 
    boolean retVal = super.dispatchTouchEvent(ev); 
    System.out.println("MyListview.dispatchTouchEvent :"+ev.getActionMasked()+" <<>> "+retVal); 
    return retVal; 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    boolean retVal = super.onInterceptTouchEvent(ev); 
    System.out.println("MyListview.onInterceptTouchEvent :"+ev.getActionMasked()+" <<>> "+retVal); 
    return retVal; 
} 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    boolean retVal = super.onTouchEvent(ev); 
    System.out.println("MyListview.onTouchEvent :"+ev.getActionMasked()+" <<>> "+retVal); 
    return retVal; 
} 

}

et, quand je jette sur cette liste, je reçois le journal en logcat suivant.

12-26 12: 38: 32,347: I/System.out (20725): MyListview.onInterceptTouchEvent: 0 < < >> faux 12 au 26 décembre: 38: 32,348: I/System.out (20725): MyListview.onTouchEvent: 0 < < >> vrai 26.12 12: 38: 32,348: I/System.out (20725): MyListview.dispatchTouchEvent: 0 < < >> vrai 26.12 12:38 : 32.388: I/System.out (20725): MyListview.onTouchEvent: 2 < < >> true 12-26 12: 38: 32.388: I/System.out (20725): MyListview.dispatchTouchEvent: 2 < < >> true 12-26 12: 38: 32.405: I/System.out (20725): MyListview.onTouchEvent: 2 < < >> true 12-26 12: 38: 32.405: I/System.out (20725): MyListview.dispatchTouchEvent: 2 < < >> true 12-26 12: 38: 32,422: I/System.out (20725): MyListview.onTouchEvent: 2 < < >> vrai 26.12 12:38: 32,422: I/System.out (20725): MyListview.dispatchTouchEvent: 2 < < >> vrai décembre 12 à 26: 38: 32,439: I/System.out (20725): MyListview.onTouchEvent: 2 < < >> vrai 12-26 12: 38: 32.439: I/System.out (20725): MyListview.dispatc hTouchEvénement: 2 < < >> true 12-26 12: 38: 32.455: I/System.out (20725): MyListview.onTouchEvent: 2 < < >> true 12-26 12: 38: 32.455: I/Système .out (20725): MyListview.dispatchTouchEvent: 2 < < >> true 12-26 12: 38: 32,473: I/System.out (20725): MyListview.onTouchEvent: 2 < < >> vrai 26.12 12: 38: 32.473: I/System.out (20725): MyListview.dispatchTouchEvent: 2 < < >> true 12-26 12: 38: 32.484: I/System.out (20725): MyListview.onTouchEvent: 2 < < >> true 12-26 12: 38: 32.484: I/System.out (20725): MyListview.dispatchTouchEvent: 2 < < >> vrai 26.12 12: 38: 32,484: I/System.out (20725): MyListview.onTouchEvent: 1 < < >> vrai 12 au 26 décembre: 38: 32,484: I/System.out (20725): MyListview.dispatchTouchEvent: 1 < < >> vrai

Je suis perplexe les observations suivantes:

  1. Pour ACTION_DOWN (code 0), onInterceptTouchEvent renvoie "false", toujours onTouchEvent est appelée, même pour ACTION_DOWN (code 0). Est-ce que onTouchEvent n'est pas censé être appelé seulement si je retourne vrai de onInterceptTouchEvent?Comme je sais, tant que onInterceptTouchEvent retourne faux, je devrais continuer à obtenir des événements dans onInterceptTouchEvent, mais ce n'est pas le cas! (Je ne pense pas vue enfant est en train de voler des événements parce que tous les événements suivants sont livrés en MyListView'sonTouchEvent lui-même.)

Quelqu'un peut-il me aider à comprendre pourquoi je reçois ces journaux? Merci.

Répondre

0

1. ListView de onTouchEvent() ne sera appelée quand aucun de ses enfants a consommé l'événement tactile ou intercepter l'événement touche lui-même (faire onInterceptTouchEvent() return true) .Donc soit votre ListView ne possède pas des tout enfant ou son onTouchEvent() de l'enfant renvoie false, donc ListView lui-même pour gérer l'événement tactile.

2.Dans vous lisez le code source de l » dispatchTouchEvent()ViewGroup, vous trouverez ceci:

 // Check for interception. 
     final boolean intercepted; 
     if (actionMasked == MotionEvent.ACTION_DOWN 
       || mFirstTouchTarget != null) { 
      final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0; 
      if (!disallowIntercept) { 
       intercepted = onInterceptTouchEvent(ev); 
       ev.setAction(action); // restore action in case it was changed 
      } else { 
       intercepted = false; 
      } 
     } else { 
      // There are no touch targets and this action is not an initial down 
      // so this view group continues to intercept touches. 
      intercepted = true; 
     } 

Cela signifie que le onInterceptTouchEvent() sera toujours appelée lorsque l'événement touche est ACTION_DOWN, mais vous ne appelé lorsque l'événement tactile n'est pas ACTION_DOWN et la variable mFirstTouchTarget (une liste liée qui contient la vue enfant pouvant être touchée) est null.

Vous pouvez faire onInterceptTouchEvent() être appelé une fois lorsque vous effleurez l'écran (ACTION_DOWN), mais lorsque l'événement touche continue la méthode ne peut pas être appelé plus parce que mFirstTouchTarget est null.And c'est souvent parce que le ListView n'a pas d'enfant ou tous les onTouchEvent() de l'enfant retournent faux comme je l'ai mentionné dans ma réponse ci-dessus.

Si vous voulez en savoir plus sur l'événement tactile, lisez plus de code source de View et ses enfants.

+0

Merci pour la réponse. Cependant, je suis passé à autre chose et je n'ai donc pas pu tester ou vérifier votre réponse. –