Touch事件分发的分析
分析一:
先看:activity_main.xml
activity_main.xml新建 TouchView.java 继承 View,实现onTouchEvent()方法和dispatchTouchEvent()方法
TouchView.java新建 TouchViewGroup.java 继承 LinearLayout,实现onTouchEvent()方法和dispatchTouchEvent()方法和onInterceptTouchEvent()方法。
TouchViewGroup.java最后是 MainActitivity的代码
然后运行看下日志输出情况:
log通过查看日志我们得出 touch的 执行顺序为:
针对父容器TouchViewGroup:ViewGroup.dispatchTouchEvent.DOWN ==> ViewGroup.onInterceptTouchEvent.DOWN
针对TouchView:View.dispatchTouchEvent.DOWN ==> View.onTouch.DOWN==>View.onTouchEvent.DOWN
针对父容器TouchViewGroup:ViewGroup.dispatchTouchEvent.UP ==> ViewGroup.onInterceptTouchEvent.UP
针对TouchView:View.dispatchTouchEvent.UP==> View.onTouch.UP==>View.onTouchEvent.UP==>View.onClick
如果我们把TouchView的onClick注释掉呢?执行的顺序又是怎么样呢?来,我们看下日志的输出:
log.2看日志的输出结果:
针对TouchViewGroup:ViewGroup.dispatchTouchEvent.DOWN ==>ViewGroup.onInterceptTouchEvent.DOWN
针对TouchView:View.dispatchTouchEvent.DOWN==>View.onTouch.DOWN==> View.onTouchEvent.DOWN
针对TouchViewGroup:ViewGroup.onTouch.DOWN==>ViewGroup.onTouchEvent.DOWN==>
ViewGroup.dispatchTouchEvent.UP==>ViewGroup.onTouch.UP==>ViewGroup.onTouchEvent.UP==>ViewGroup.onClick
大家发现和第一次有什么区别了吗?当TouchView和TouchViewGroup都设置了onClick事件之后,如果点击的地方覆盖了,TouchViewGroup的点击事件不会被执行。
如果我们在TouchView的onTouch事件中返回true呢?看下日志输出情况:
log发现onclick事件没有被执行,有没有发现?我们来分析下这种情况:
所有触摸事件都会执行 view中的dispatchTouchEvent()这个事件 看下这个方法中的代码我们发现
有这么一段代码:
ListenerInfo 是一个监听集合类,result 默认 为 false 。因为我们设置 onTouchListener 所以这里的 li.onTouchListener肯定不会空,当用户点击的时候 就会执行这个代码 li.onTouchListener.onTouch(this,event)然后回调到onTouch()发放中,这个方法默认返回 false,因此这个if()是进不去的,result得到的值就是 false。但是我们在onTouch的回调中 手动设置返回了 true,所以li.onTouchListener.onTouch(this,event) 得到的就是 true。此时result会被赋值为 true。导致 onTouchEvent(event)就不会在执行了。我们看下 onTouchEvent(event) 里面的代码:
public boolean onTouchEvent(MotionEvent event)==》public boolean performClick()。可能不同版本的api不一样,但是都离不开这两个方法,大家可以找一下,我这里就直接贴出来了。
不难发现,onClick()事件在这里回调执行。到这里就验证了 如果在 onTouch()事件中返回false,onClick()事件才会被执行,如果返回true,则不会执行。