事件分发
Android事件分发机制:
Android的view是树形结构的,view可能会重叠到一起,点击重叠位置的时候,会有多个view响应这个点击事件,那这个事件到底该由谁来处理,就出现Android的事件分发。
事件分发涉及到三个类,activity、viewgroup、view。activity包含一个window对象,这个对象由phonewindow来实现的,phonewindow将decrview作为窗口的根view,他的内部划分为两个区域,titleview和conntentview,咱们平时写的布局就是展示在contentview中。viewgroup是一个可包含view的容器,其本质也是一个view。
整个分发的流程基本上围绕真三个方法展开的,dispathTouchEvent()来进行事件分发、ouTouchEvent()来处理点击事件、onlnterceptTouchEvent()用来进行事件的拦截,这个方法只有viewgroup中有;ontouchevent和oninterceptTouchEvent都是在dispatchTouchEvent中调用。
- 当用户点击了屏幕,事件先传递到activity中,activity的dispathchTouchEvent方法调用super将事件分发到phonewindow的内部类DecorView将事件交给viewGroup处理
- viewgroup在dispathTouchEvent内部通过一个for循环来遍历在view,因为在子view可能重叠情况,所以他是一个倒叙的遍历,也就是说优先便利上层的子view,如果有子view,调用view的dispathTouchEvent方法,如果没有则将事件传递给自身的ontouchevent方法中。viewgroup的activon_down事件中,会调用onInterceptTouchEvent去判断是否拦截,拦截就直接在onTouchEvent返回true,不拦截就睡把事件分发给下一个viewgroup,onInterceptTouchEvent默认返回false,一般不会对事件进行拦截(除非改viewgroup没有子view,切其自身设置了处理事件的监听,这个方法在acion——move或action——up的时候不执行)
- view是最底层控件,不会有onInterceptTouchEvent,它的选择就只有处理或者不处理,处理就会在onTouchEvent进行处理并返回true,不处理的话也就不会被销毁,会把事件回传给viewgroup的ontouchevent方法,viewgroup也是一样,如果在ontouchevent中return true , 就消费了这个事件,反之就是一层一层的往上传递,直到回传给activity,如果activity还不处理,那么这个事件才会被销毁。
举一个工作的例子:比如公司有一个新任务,老板交给了项目经理去处理,项目经理如果自己处理,事件的传递就到此结束了,如果项目经理没有处理,可以交给手下的基层员工去处理,如果处理不了,直接将任务返回给项目经理,同样如果项目经理能处理,处理后事件终止,如果处理不了只能返回给老板,这个时候老板必须处理这个事件了,不能继续向下传递,事件终止。