onInterceptTouchEvent only gets ACTION_DOWN

后端 未结 3 1291
暗喜
暗喜 2020-11-29 01:34

Why do ViewGroup\'s only get ACTION_DOWN in the onInterceptTouchEvent? According to the docs, as long as false is returned it should r

相关标签:
3条回答
  • 2020-11-29 01:35

    I'll answer my own question: onInterceptTouchEvent only get called if the parent has a child view which returns "true" from onTouchEvent. Once the child returns true, the parent now has a chance to intercept that event.

    enter image description here

    0 讨论(0)
  • 2020-11-29 01:35

    I get the same problem. I had read many posts about it:
    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

    I also had read android doc:
    http://developer.android.com/training/gestures/viewgroup.html
    http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)

    All answers are same. I tried many times, always not get onInterceptTouchEvent () be called if not down event.

    I read source code, I guess that something is changed:

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


    According above code, onInterceptTouchEvent(ev) is only be called when MotionEvent.ACTION_DOWN, this is what we tried and found. So, what I guess is, the code is changed, but doc not.

    If you want spy or monitor all the events include those been sent to child views, you can override dispatchTouchEvent() like this:

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

    I have the runnable code at: https://github.com/maxyou/gesturebutton/blob/master/src/com/maxproj/gesturebutton/GestureButtonLayout.java

    0 讨论(0)
  • 2020-11-29 01:51

    [Touch event flow]

    The official doc

    Activity.dispatchTouchEvent(MotionEvent) - This allows your Activity to intercept all touch events before they are dispatched to the window.

    ViewGroup.onInterceptTouchEvent(MotionEvent) - This allows a ViewGroup to watch events as they are dispatched to child Views. It is recursively function (from parent to parent)

    ViewParent.requestDisallowInterceptTouchEvent(boolean) - Call this upon a parent View to indicate that it should not intercept touch events with onInterceptTouchEvent(MotionEvent).

    0 讨论(0)
提交回复
热议问题