写在前面的话:
之前对于android的触摸以及拦截方面知识了解个大概,处在在项目中能用的阶段,最近自己整理了下结合网上的教程进行了深入了解。
现将自己的想法写出来,主要是自己记录而已。
先从view开始讲起,对于view而言,任何触摸控件的操作都会触发它的dispathonTouchEvent()方法,在这个方法的源码中首先有一个if判断,判断条件有三个,这三个全部为true的时候才会返回true,否则会去执行onTouchEvent方法。
三个条件为 1)控件是否注册onTouchListener 2)空间是否enable(恒为true) 3)onTouch方法的返回值
由此可见关键点在于第三个也就是onTouch的返回值,如果onTouch返回true,则不执行onTouchEvent,这也侧面说明了onTouch比onTouchEvent优先执行。
若onTouch返回fasle,则去执行onTouchEvent,在它的源码中会看到调用了onClickLintener,前提条件是该控件clickable属性为true,否则会返回fasle,会导致之后饿控件接收不到ACTION_MOVE以及ACTION_UP。所以现在梳理一下点击顺序。
系统检测到触摸事件后,会直接调用dispathonTouchEvent,而后根据onTouch的返回值判断是否调用onTouchEvent,然后再根据控件是否clickable返回true还是fasle是否接受后续事件。
onTouch 》 onTouchEvent 》 onClick
以上是view的情况,如果是viewgroup的情况呢? viewgroup有一个特殊的拦截方法oninterrupe 根据他返回true或者fasle来判断父view是否要拦截掉这次,自己消费 如果返回true 就油父view的onTouchEvent来处理消息 否则就交给子view的dispatonTouchEvent去执行 这下就跟我们前面讲的接上了,触摸事件是从上往下传递的,如果下级view不处理,则消息又会返回上级,大致就是这个逻辑。
触摸的拦截大致就是这样,遇到再复杂的情况只要将其分解出来,问题便不会那么复杂了。