最近有点无聊,出来玩一玩代码
对于一个Android开发者来说,掌握事件的分发是非常重要的,也是Android开发中非常非常难的一部分(ps:可能我比较笨,大神可以忽略)只有掌握好了它,我们才能很熟练的来解决复杂布局的一些滑动冲突。
大神分析链接地址:https://blog.csdn.net/guolin_blog/article/details/9097463
好啦,废话到此为止
首先,我们先来看一看单一控件的事件分发。
控件可以分为两种,默认可点击的(Button,ImageButton等),默认不可点击的(ImageView,各种的布局LinearLayout等)
我们先分析默认可点击的Button
一 。Button分析
1.分析dispatchTouchEvent
我们在代码中自定义一个button,给它设置好触摸事件和点击事件。然后,嘿嘿。。。点它一下。去查看日志输出:
发现事件分发的大致流程是这样的:dispatchTouchEvent》onTouch》onTouchEvent》onClick
前三行的日志为执行手指按下触发的Down事件,发现其中少了一个点击事件的打印输出,说明点击事件根本不在这边Down事件当中,就这么简单,哈哈。最后我们发现,点击事件是在UP事件中触发,也是最后一个触发的。
如果我在dispatchTouchEvent中返回true,那打印出来的日志就会自有三行(dispatchTouchEvent的down,move,up),说明事件在分发的开始就被消耗了。如果我在dispatchTouchEvent的任意一个中返回false,那剩下的事件就不会执行。废话不多说,直接上代码
看到这里可以明确,事件分发要想往下分发,需调用父类的dispatchTouchEvent才行。
有看到过有些人的事件分发是这样写的
查看日志可以发现其down事件已经分发到了onTouchEvent,但是由于在dispatchTouchEvent中返回了false,所以事件就被消费了。如果将上图中圈起来的部分改成true(那相当与没有修改),事件分发会照常进行。
如果将中间的move改为true,日志如下。事件分发的move事件到dispatchTouchEvent就不再向下了,而是执行下一个事件
如果是dispatchTouchEvent中的Move返回false,那事件就会在这里被消费。
现在分析一下如果是在第三个中返回true,日志如下
可以看到按钮的点击事件消失了。
2.分析onTouch事件
控件设置OnTouchListener,最后里面有一个返回值为false,表示不拦截onTouch事件.如果将其改为true,后面的OnTouchEvent,滑动事件,点击事件都将被屏蔽。如果我们修改其为下图
查看日志发现down事件到这边就停止了,然后由于这边down里面的返回值为true,触摸事件继续执行。日志如下:
发现点击事件消失了。如果修改的为up效果一样。修改move对点击事件没影响,但会屏蔽控件(如listview)的滚动.可以得出结论,down和up都得到执行时点击事件才会响应。
3.分析OnTouchEvent
这种简单的三种只修改最后的返回值的就不分析了,都在图上
二. ImageView 分析
对于默认不可点击的控件,其设置OnTouchListener是不生效的。
onTouch 事件是dispatchTouchEvent分发到onTouchEvent的前提条件判断。1.OnTouchListener!=null 2.可点击 3.onTouch 返回值 三个为true就拦截。onTouch排第三判断,如果前面的任何一个为false就会停止当前的判断,不再执行控件的onTouch(例如给ImageView设置触摸事件)
如果一个控件设置了点击事件,那它就会默认变成可点击的控件。其事件分发就和button一样。
开始分析
差不多,就分析到这了,还是要自己动手去操作会理解深刻一些。