android事件传递ACTION_DOWN、ACTION_MOVE、ACTION_UP的深入研究

对于事件的传递大概的流程,都比较清楚。这里主要探讨下事件流不同部分的拦截会有什么样的影响。
以如下布局为例

<com.listener.administrator.clicklistenerapplication.MLinearlayout1
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent">
        <com.listener.administrator.clicklistenerapplication.MLinearlayout
            android:layout_width="match_parent"
            android:orientation="vertical"
            android:layout_height="match_parent"
            >
            <com.listener.administrator.clicklistenerapplication.MButton
                android:layout_width="400dp"
                android:layout_height="400dp"
                android:text="nishao" />
        com.listener.administrator.clicklistenerapplication.MLinearlayout>

    com.listener.administrator.clicklistenerapplication.MLinearlayout1>

每个自定义布局重写其dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三个方法并分别在其MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE、MotionEvent.ACTION_UP。打印日志。

1问:当MButton(默认onTouchEvent 的ACTION_DOWN是返回true的)onTouchEvent 的ACTION_DOWN 事件返回true时,其父View、onTouchEvent 是否会执行?

答:很显然不会执行,因为一旦onTouchEvent 的ACTION_DOWN事件返回true就意味着接下来的MOVE、UP 事件都将在此View中处理。其MOVE和UP事件返回值不对以上结论产生影响。

2问:MLinearlayout 布局中的 onInterceptTouchEvent, ACTION_DOWN返回值为true。对事件的影响。

答:onInterceptTouchEvent 这么做即是当前布局拦截了事件。如果onTouchEvent down返回true的话。接下来的一系列down ,move和up都将在MLinearlayout 的 onTouchEvent中处理,其子View MButton不会接受到点击事件。如果MLinearlayout 的onTouchEvent ACTION_DOWN 并没有消费即返回false。接下来的move和up事件将不再分发。 可以看到如下日志
android事件传递ACTION_DOWN、ACTION_MOVE、ACTION_UP的深入研究_第1张图片
MLinearlayout onInterceptTouchEvent DOWN事件返回TRUE拦截。onTouchEvent默认不处理即返回的是false。日志如上
android事件传递ACTION_DOWN、ACTION_MOVE、ACTION_UP的深入研究_第2张图片
MLinearlayout onInterceptTouchEvent DOWN事件返回TRUE拦截。onTouchEvent DOWN 事件返回TRUE ,即告诉activity后续的一系列事件有人处理请继续分发。然后接下来的MOVE UP事件交给MLinearlayout处理。注意个细节:MLinearlayout的onInterceptTouchEvent 方法不再执行了。因为一旦当前view onTouchEvent Down事件返回true 则当前的View的onInterceptTouchEvent 不再调用,而是直接调用onTouchEvent 方法。

3问:MLinearlayout 布局中的 onInterceptTouchEvent, ACTION_DOWN返回值为false。 ACTION_MOVE 返回TRUE对事件的影响和2的情况有何不同。

答:android事件传递ACTION_DOWN、ACTION_MOVE、ACTION_UP的深入研究_第3张图片
上面日志可以看出事件传递流,1、 ACTION_DOWN事件通过一系列的 dispatchTouchEvent、onInterceptTouchEvent 关卡到达MButton的onTouchEvent 中被拦截,正常情况接下来的move up事件都将在MButton中处理。但是MLinearlayout 拦截下了 ACTION_MOVE事件,一旦拦截则接下来事件都将交给MLinearlayout 的 onTouchEvent 处理。这块和2中还是有区别的。

4 问:dispatchTouchEvent 中ACTION_DOWN 的返回值对事件传递的影响?

我们将MLinearlayout dispatchTouchEvent ACTION_DOWN 返回值为TRUE 和false看下日志。

这里写图片描述
以上为返回false的日志。这个的返回值和 onTouchEvent 返回false是一样的效果,实时是dispatchTouchEvent 返回值在一定情况下就是onTouchEvent 的返回值。这个可以研究下源码(这里暂不讨论)。

android事件传递ACTION_DOWN、ACTION_MOVE、ACTION_UP的深入研究_第4张图片

以上是返回true 日志 和在onInterceptTouchEvent 中拦截是一样的。

5 问: dispatchTouchEvent 中ACTION_MOVE 的返回值对事件传递的影响?

android事件传递ACTION_DOWN、ACTION_MOVE、ACTION_UP的深入研究_第5张图片

上面是我们在MLinearlayout ACTION_MOVE中返回true 的日志。比较有意思。只是拦截了move事件其他的事件还都是在MButton中处理。而且MLinearlayout 的onToucheEvent 并没有被调用。说明这个只是拦截消失了,并不是拦下处理了。

android事件传递ACTION_DOWN、ACTION_MOVE、ACTION_UP的深入研究_第6张图片

和上面类似。具体原因稍后在源码中解析。

总结:通过以上几个问题可以得出结论:

1,ACTION_DOWN 事件决定着接下来的一系列事件的传递方向。返回TRUE ,则该一系列操作事件将由当前View的onToucheEvent 处理。返回false 事件将继续传递。直至返回Activity. Activity接收到其分发出去的ACTION_DOWN返回值false,则不再分发接下来的MOVE UP 事件。

2、dispatchTouchEvent 分两种情况:ACTION_DOWN 时return 和 ACTION_MOVE 、ACTION_UP return 。ACTION_DOWN:返回TRUE和该View 的onTouchEvent ACTION_DOWN返回true 是一样的即告诉activity 当前View可以处理接下来的事件流。 返回false 结束事件剩下的也不再传递。ACTION_MOVE 、ACTION_UP :这种情况说明其子View中已经开始处理事件流,在这里return直接导致该部分事件流不再继续传递,对于没有return的还按照正常的流程传递。

3、onInterceptTouchEvent 不论什么时候拦截,接下来的事件都将传递给当前的onTouchEvent处理接下来的事件流。例如在当前View的onInterceptTouchEvent 的ACTION_MOVE 中返回了true,则接下来的ACTION_MOVE、ACTION_UP都将传递给当前view的onTouchEvent处理。其子View将不再接收处理剩下的事件。

如有错误之处,请大家多多指教,欢迎讨论。转载请注明出处
http://blog.csdn.net/lijiuche/article/details/70807672

你可能感兴趣的:(Android-随笔)