三个函数 dispatchTouchEvent分发事件 onInterceptTouchEvent截断事件 onTouchEvent处理事件 public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent 2.特殊的View子类ViewGroup则还有一个方法: public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent 3.分发 dispatchTouchEvent 收到触碰,则向最外层的View传递消息,再向子层的View分发 4.拦截: onInterceptTouchEvent 拦截返回true表示要拦截消息,不要再向子View传递(这里的子View不是继承关系,而是包容关系)。返回false则表示不拦截消息,可以继续向下一层级的View传递消息,子View将可以dispatchTouchEvent 收到触碰消息再分发消息 5.消息处理: onTouchEvent 处理事件,拦截了消息,或者是最后一个收到消息的View调用此方法来处理事件,若返回true,则表示正确接收并处理。若返回false则表示没有被处理,将向父View传递(这里的父View不是继承关系,而是包容关系) 再来看看Android的官方文档正解 onInterceptTouchEvent()与onTouchEvent()的机制: 1. down事件首先会传递到onInterceptTouchEvent()方法 2. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false, 那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最 终的目标view的onTouchEvent()处理 3. 如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true, 那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样 传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。 4. 如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一 层次的view的onTouchEvent()处理 5. 如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递 给该view的onTouchEvent()处理 第5条注,即down事件返回true.move事件up事件才会到onTouchEvent里面处理。 记录下遇到的坑 上面是从别人那转载过来的。 第3条有错误,onInterceptTouchEvent接收Down和Move类型的事件。不仅仅只有Down。 第4条有补充,前提是在onInterceptTouchEvent返回false的情况下。如果返回true它也不会往上发。即使onTouchEvent返回false。 ViewPager左右滑动的时候onInterceptTouchEvent返回true。把事件拦截下来。 同样的ListView上下滑动时候onInterceptTouchEvent返回true把事件拦截下来。他们也不会往上层传消息。 我曾遇到这样的情况,ViewPager外面套了一层ViewGroup,viewpager里面嵌了一个listView。ViewGroup死活收不到消息。左右滑一直被ViewPager拦截。重写onInterceptTouchEvent的返回值设置为false,ViewPager逻辑又不会执行。这告诉我们有时候返回值不是说改就能改的。对于那些"污"的控件。远不如ViewGroup和View来的纯洁。 解决方式: 利用onInterceptTouchEvent可以接收Down和Move类型的事件。在判断需要ViewGroup处理事件的时候直接使用bool值将其拦截下来。这里需要重写ViewGroup的onInterceptTouchEvent。 |
|
来自: Dragon_chen > 《Android》