2012-11-08 22 views
22

为什么ViewGroup唯一获得在onInterceptTouchEventACTION_DOWN?根据文档,只要返回false,它就会收到所有的事件类型。 http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29 点#3。onInterceptTouchEvent只得到ACTION_DOWN

示例代码:

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

回答

45

我会回答我的问题:如果父母有从的onTouchEvent返回“真”子视图onInterceptTouchEvent只被调用。一旦孩子回复真实,父母现在有机会截获该事件。

enter image description here

+0

哪有父母如果孩子已经发送了它,那么拦截事件? –

+0

孩子不会派遣触摸事件(通常)。触摸事件从父母到孩子迭代地发泡。下来它在onTouchTouchEvent和即将到来的onTouchEvent。它继续冒泡直到有人回复真实。 – user123321

+0

如果我有一个onTouchListener一查看,我添加到一个ViewGroup中。这个监听器被调用,开始一些行为,然后返回false。之后,ViewGroup可以“截取”事件?如果处理程序的代码已经执行? –

5

我得到同样的问题。我已经看了很多帖子一下吧:
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

我也读了Android的文档:
http://developer.android.com/training/gestures/viewgroup.html
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)

所有的答案都是一样的。我试过很多次,始终没有得到onInterceptTouchEvent ()被调用,如果不下来的事件。

我读的源代码,我想有些事情是改变:

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


根据上面的代码,onInterceptTouchEvent(ev)是只有当MotionEvent.ACTION_DOWN,这就是我们试图发现调用。所以,我猜想,代码被改变了,但是doc不是。

如果你想间谍或者监控所有的活动,包括那些被送到孩子的意见,您可以覆盖dispatchTouchEvent()这样的:

@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); 
} 

我已经在运行的代码:https://github.com/maxyou/gesturebutton/blob/master/src/com/maxproj/gesturebutton/GestureButtonLayout.java

+0

我阅读了源代码并找到了这一点。 –

+0

非常感谢!我花了大约3个小时尝试不同的解决方案,但这个非常棒! –