2012-11-08 11 views
22

Perché lo ViewGroup riceve solo ACTION_DOWN nello onInterceptTouchEvent? Secondo i documenti, finché viene restituito il falso, dovrebbe ricevere tutti i tipi di evento. http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29 Punto # 3.onInterceptTouchEvent ottiene solo ACTION_DOWN

codice di esempio:

public class MainActivity extends Activity { 

    private static final String TAG = MainActivity.class.getSimpleName(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(new Container(this)); 
    } 

    private class Container extends LinearLayout { 

     public Container(Context context) { 
      super(context); 
      setBackgroundColor(0xFF0000FF); 
     } 

     @Override 
     public boolean onInterceptTouchEvent(MotionEvent ev) { 
      Log.i(TAG, "onInterceptTouchEvent"); 
      int action = ev.getActionMasked(); 
      switch (action) { 
      case MotionEvent.ACTION_DOWN: 
       Log.i(TAG, "onInterceptTouchEvent.ACTION_DOWN"); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       Log.i(TAG, "onInterceptTouchEvent.ACTION_MOVE"); 
       break; 
      case MotionEvent.ACTION_CANCEL: 
      case MotionEvent.ACTION_UP: 
       Log.i(TAG, "onInterceptTouchEvent.ACTION_UP"); 
       break; 
      } 
      return super.onInterceptTouchEvent(ev); 
     } 
    } 
} 

risposta

45

io rispondere alla mia domanda: onInterceptTouchEvent ottenere chiamato solo se il genitore ha una vista bambino che restituisce "vero" da onTouchEvent. Quando il bambino ritorna vero, il genitore ha ora la possibilità di intercettare quell'evento.

enter image description here

+0

Come può il genitore intercettare l'evento se il bambino l'ha già spedito? –

+0

i bambini non inviano eventi di tocco (normalmente). La bolla di eventi tattili dal genitore ai bambini in modo iterativo. Scendendo si trova suInterceptTouchEvent e in arrivo è onTouchEvent. Continua a gonfiarsi finché qualcuno non ritorna vero. – user123321

+0

Se ho una vista con un onTouchListener, che aggiungo a un ViewGroup. Questo ascoltatore viene chiamato, inizia un comportamento, quindi restituisce false. Dopo che il ViewGroup può "intercettare" l'evento? Se il codice del gestore è già stato eseguito? –

5

ottengo lo stesso problema. Avevo letto molti post su di esso:
onInterceptTouchEvent only gets ACTION_DOWN
onInterceptTouchEvent's ACTION_UP and ACTION_MOVE never gets called
onInterceptTouchEvent, onTouchEvent only see ACTION_DOWN
onInterceptTouchEvent never receives action_move

Ho anche aveva letto doc Android:
http://developer.android.com/training/gestures/viewgroup.html
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)

Tutte le risposte sono le stesse. Ho provato molte volte, non sempre suInterceptTouchEvent () essere chiamato se non giù evento.

ho letto il codice sorgente, immagino che qualcosa è cambiato:

@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    if (mInputEventConsistencyVerifier != null) { 
     mInputEventConsistencyVerifier.onTouchEvent(ev, 1); 
    } 

    boolean handled = false; 
    if (onFilterTouchEventForSecurity(ev)) { 
     final int action = ev.getAction(); 
     final int actionMasked = action & MotionEvent.ACTION_MASK; 

     // Handle an initial down. 
     if (actionMasked == MotionEvent.ACTION_DOWN) { 
      // Throw away all previous state when starting a new touch gesture. 
      // The framework may have dropped the up or cancel event for the previous gesture 
      // due to an app switch, ANR, or some other state change. 
      cancelAndClearTouchTargets(ev); 
      resetTouchState(); 
     } 

     // 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; 
     } 


Secondo sopra il codice, onInterceptTouchEvent(ev) è essere chiamato solo quando MotionEvent.ACTION_DOWN, questo è quello che abbiamo provato e abbiamo trovato. Quindi, quello che immagino sia, il codice è cambiato, ma non doc.

Se volete spia o monitorare tutti gli eventi includono quelli stato inviato alle viste bambino, è possibile ignorare dispatchTouchEvent() in questo modo:

@Override 
public boolean dispatchTouchEvent(MotionEvent event) { 
    MyLog.d(MyLog.DEBUG, "dispatchTouchEvent(): "+event.getAction()); 
    if (isEnabled()) { 
     MyLog.d(MyLog.DEBUG, "dispatchTouchEvent()2: "+event.getAction()); 

     processEvent(event);//here you get all events include move & up 

     super.dispatchTouchEvent(event); 

     return true; //to keep receive event that follow down event 
    } 
    return super.dispatchTouchEvent(event); 
} 

Ho il codice eseguibile in: https://github.com/maxyou/gesturebutton/blob/master/src/com/maxproj/gesturebutton/GestureButtonLayout.java

+0

Ho letto il codice sorgente e ho trovato anche questo. –

+0

Grazie mille! Ho trascorso circa 3 ore provando soluzioni diverse, ma questa è davvero carina! –

Problemi correlati