首先想要了解事件的分发和处理,就要先了解什么是触摸事件
什么是触摸事件?
顾名思义,触摸事件就是我们触碰屏幕之后产生的事件,一般触碰到屏幕之后会触发两个或者三个事件
- 按下 Action_Down
- 如果滑动 Action_Move
- 抬起 Action_Up
这些事件封装成了一个类『MotionEvent』,如果重写onTouchEvent()方法,该方法的参数就是一个MotionEvent对象。在MotionEvent里不止有这几个事件,还可以取出当前触摸的坐标点等等。
当然,这只是在一个View中,但是我们知道,Android的View结构是树形的,View可以放在一个ViewGroup当中,然后这个ViewGroup当中又嵌套一个ViewGroup。所以当我触摸屏幕的时候到底是谁来执行这个事件?这样就引出了『事件拦截』
我们想象一下场景
一个总经理,一个技术经理,然后干活的你。总经理把任务布置给技术经理,然后技术经理把任务安排给了你。过了一会你把任务完成,交给技术经理,技术经理觉的不错,就交给了总经理,这样这个任务就完成了
了解了这个流程之后,对于事件拦截也就理解了小半了,下面来一个实例看一下
首先我们自定义两个ViewGroup和一个View分别对应一个总经理一个技术经理和一个干活的。
在两个ViewGroup中我们主要重写三个方法
- dispatchTouchEvent()
- onInterceptTouchEvent()
- onTouchEvent()
然后在View中重写两个方法
- dispatchTouchEvent()
- onTouchEvent()
然后我们在这几个方法中什么都不改,只是在里面打印Log日志来看一下执行的顺序。
XML布局如下:
<com.github.wanglu1209.androidqunyingzhuan.ViewGroupA
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.wanglu1209.androidqunyingzhuan.ViewGroupB
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.wanglu1209.androidqunyingzhuan.MyView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.github.wanglu1209.androidqunyingzhuan.ViewGroupB>
</com.github.wanglu1209.androidqunyingzhuan.ViewGroupA>
现在运行程序,查看Log,如下:
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
View dispatchTouchEvent
View onTouchEvent
ViewGroupB onTouchEvent
ViewGroupA onTouchEvent
可以看的出来,正常情况下事件的传递顺序为:
ViewGroupA -> ViewGroupB -> View
事件的处理顺序为:
View -> ViewGroupB -> ViewGroupA
其中事件传递的返回值:
- True 拦截,不继续传递
- False 不拦截,传递
事件处理的返回值:
- True 处理完毕,不交给上级
- False 交给上级
事件分发
现在我们给代码做一些改动,把ViewGroupA的onInterceptTouchEvent()的返回值改为True,查看一下log
log如下:
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupA onTouchEvent
这里我们直接在最外侧的ViewGroupA中把事件拦截了下来,所以后面的ViewGroupB和View都没有接收到触摸事件。如果我们在ViewGroupB中拦截事件,那么log如下;
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
ViewGroupB onTouchEvent
ViewGroupA onTouchEvent
这样把Log打印出来就对事件的拦截和传递有了一个清晰的认识,下面来看一下事件的处理
事件处理
开始的时候我们说过,当你完成了任务之后会像你的项目经理报告,需要上级的确认,所以你的事件处理返回false,如果有一天你不干了,那么你也就不用给上级报告了,返回了true,来看一下log
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
View dispatchTouchEvent
View onTouchEvent
ViewGroupA dispatchTouchEvent
ViewGroupA onInterceptTouchEvent
ViewGroupB dispatchTouchEvent
ViewGroupB onInterceptTouchEvent
View dispatchTouchEvent
View onTouchEvent
事件传递和以前一样依次的传递下来,但是处理事件到View这里就结束了,没有向上级传递,如果给ViewGroupB的onTouchEvent的返回值true,那么事件处理到ViewGroupB就结束了。
这样一来,事件的分发和处理就了解了
最后
爱生活,爱小丽,爱Android
网友评论