对touch事件传递的简单理解

来源:互联网 发布:事业单位粉笔软件 编辑:程序博客网 时间:2024/06/06 10:47

对View事件传递的理解,看的这篇。
对事件传递有了大致的了解。onInterceptTouchEvent 函数决定是否将事件拦截,拦截之后,该控件的所有子控件接收不到这个事件。onTouchEvent 函数判断是否消费此事件,在父控件把事件传递到子控件的过程中,假设都没有拦截,那么消息会传递到底层控件,底层控件可以选择消费或者不消费,如果消费,那么事件到此终止,如果没有消费,则一层一层传递给父类。如果中途被拦截了,那么拦截的那个控件充当上述过程的底层控件。最重要的,在这个过程中,事件所经过的控件,都执行了onTouchEvent 方法,只不过返回值不同确定消费与否而已,比如,父控件onTouchEvent返回值为true,子控件为false,且父控件没有拦截,事件的终点是父控件,但是子控件的onTouchEvent方法是执行了!只不过没有消费。在touch过程中,只有action_dowm事件消费了,才能消费move和up事件,也好理解,不按下,怎么移动和抬起。
之前在研究下拉刷新控件时,遇到的问题:当下拉区域宽度大于临界值时,这时松开手指则开始刷新,如果这时我想取消,那么只能手指向上滑,使这个宽度小于临界宽度再松手就好了,但是,实际的情况是,这时手指向上滑,ListView也开始滑动了,下拉区域就在屏幕之外了。正确的应当是把ListView禁止滑动,过会再取消禁止,当时的解决办法是在ListView onTouchEvent()中,判断这一情况,并直接返回true就可以解决。当时的理解很肤浅,只想返回true就把事件消费了,就完事了。现在想想完全不是那回事,所以重新看那段代码。下拉刷新控件的简单分析
尝试把ListView中super.onTouchEvent(ev)输出,发现这个值是true,感觉不对啊,和我想的不同,既然都是返回true,为什么还会有上述的解决办法。于是猜想super.onTouchEvent(ev)不仅仅单纯返回一个true那么简单,可能还响应和改变ListView的滚动条,打开AbsListView.java,查看这个方法,果然有很多很多代码,这样就可以解释了,直接返回true,从而没有执行AbsListView中默认的onTouchEvent方法,所以滚动条才没有滚动。
ListView相当于父控件,item是子控件,而item布局里的其他控件就是子子控件,按照功能需求可以通过控制touch事件传递来实现。

0 0