目    录(本篇字数:955)

案例

我们来看一个这样的案例,目的是熟悉android事件分发、拦截的流程,例子如下:

android studio 打印机 打印_android事件分发log打印

如上图,ViewGroupA内嵌ViewGroupB存放着一个ImageView,一个简单明了的布局,让我们以此来揭开View的事件分发机制。

代码非常简单,ViewGroupA和ViewGroupB分别重写了dispatchTouchEvent()、onInterceptTouchEvent()、onTouchEvent();而ImageView因为不是容器没有onInterceptTouchEvent(),只是在这三个方法打印了Log,主要是分析我们的Log看看事件分发、拦截的流程。我只贴一个ViewGroupA的代码, 其他基本一样我就不贴出来了。

/**
* @Created by xww.
* @Creation time 2018/8/16.
*/
public class ViewGroup_A extends FrameLayout {
public ViewGroup_A(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.i("---ViewGroup_A---", "dispatchTouchEvent: " + ev.getAction());
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean isIntercept = false;
Log.i("---ViewGroup_A---", "onInterceptTouchEvent: " + ev.getAction() + " ----是否拦截:" + isIntercept);
return isIntercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean isTouch = false;
Log.i("---ViewGroup_A---", "onTouchEvent: " + ev.getAction() + " ----是否消费:" +isTouch);
return isTouch;
}
}

View事件流程分析

(Children是ImageView,0表示DOWN事件,1表示UP事件)

注意:down ---> up 是完整性事件,activity默认设置不消费。

一、不拦截、不消费。

android studio 打印机 打印_事件传递_02

它的完整流程是:

activity(分发DOWN事件)---> A (未拦截,分发) ---> B (未拦截,分发) ---> children(分发)---> children(未消费)---> B (未消费)---> A (未消费) ---> activity(未消费 UP事件)

二、不拦截、仅children消费。

android studio 打印机 打印_android事件分发log打印_03

activity(分发DOWN事件)---> A (未拦截,分发) ---> B (未拦截,分发) ---> children(分发)---> children(消费 UP事件)

三、不拦截、仅B消费。

android studio 打印机 打印_android事件分发log打印_04

activity(分发DOWN事件)---> A (未拦截,分发) ---> B (未拦截,分发) ---> children(分发)---> children(未消费)---> B (消费UP事件)

四、不拦截、仅A消费。

android studio 打印机 打印_ide_05

activity(分发DOWN事件)---> A (未拦截,分发) ---> B (未拦截,分发) ---> children(分发)---> children(未消费)---> B (未消费)---> A (消费UP事件)

五、B拦截,不消费。

android studio 打印机 打印_事件传递_06

activity(分发DOWN事件)---> A (未拦截,分发) ---> B (拦截,未分发)---> B (未消费)---> A (未消费) ---> activity(未消费 UP事件)

B拦截了事件,children即收不到事件传递,由谁拦截由谁结束分发,那将由谁开始处理onTouchEvent()事件。

六、A拦截,不消费。

android studio 打印机 打印_事件分发机制_07

activity(分发DOWN事件)---> A (拦截,未分发)---> A (未消费) ---> activity(未消费UP事件)

七、不拦截,children不分发,仅B消费。

android studio 打印机 打印_ide_08

发现onTouchEvent()事件全部消失了,即使你有消费它,但是children不分发,相当于所有View的onTouchEvent()事件根本没被消费,看我们的日志及屏幕的Toast情况。

android studio 打印机 打印_ide_09

可以看到,Log的确有事件的分发,到了children时我们将它终止分发,所有的onTouchEvent()不消费,屏幕也无法Toast成功。所以大多数情况下,我们不会去终止事件的分发。