繁体   English   中英

onInterceptTouchEvent 只获得 ACTION_DOWN

[英]onInterceptTouchEvent only gets ACTION_DOWN

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

示例代码:

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

我会回答我自己的问题:只有当父视图有一个从 onTouchEvent 返回“true”的子视图时,才会调用 onInterceptTouchEvent。 一旦孩子返回真,父母现在有机会拦截该事件。

在此处输入图片说明

我遇到同样的问题。 我读过很多关于它的帖子:
onInterceptTouchEvent 只获得 ACTION_DOWN
onInterceptTouchEvent 的 ACTION_UP 和 ACTION_MOVE 永远不会被调用
onInterceptTouchEvent, onTouchEvent 只看到 ACTION_DOWN
onInterceptTouchEvent 从不接收 action_move

我也读过android doc:
http://developer.android.com/training/gestures/viewgroup.html
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)

所有的答案都是一样的。 我试了很多次,总是得不到onInterceptTouchEvent() if not down 事件被调用。

我阅读了源代码,我想有些东西已经改变了:

@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 ,这就是我们试图发现。 所以,我猜是,代码已更改,但文档未更改。

如果您想监视或监视所有事件,包括发送到子视图的事件,您可以像这样覆盖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

dispatchTouchEvent、onInterceptTouchEvent、requestDisallowInterceptTouchEvent

【触摸事件流程】

官方文档

Activity.dispatchTouchEvent(MotionEvent) - 这允许您的 Activity 在将它们分派到窗口之前拦截所有触摸事件。

ViewGroup.onInterceptTouchEvent(MotionEvent) - 这允许 ViewGroup 在事件被分派到子视图时观看它们。 它是递归函数(从父级到父级)

ViewParent.requestDisallowInterceptTouchEvent(boolean) - 在父视图上调用它以指示它不应使用 onInterceptTouchEvent(MotionEvent) 拦截触摸事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM