您的位置:首页 > 移动开发 > Android开发

包子理论解释Android点击事件的拦截与分发

2013-12-26 15:22 344 查看
近来项目中多处界面用到自定义控件,有感于对Android点击事件的拦截与分发,同时也在网上看到很多关于这类的帖子,讲的透彻的都是从Android底层源码说起,不乏某些大牛一边源代码一边测试demo的演示,如有需要的童鞋请走下边传送门。
从源码分析点击事件的拦截与分发

看过后又回来的童鞋,或者说想立刻了解我所言包子理论的童鞋,请接着往下看。

(MotionEvent event)这个东西相信大家都不陌生,我就将之称为包子。

(View view)这个如果谁不认识,出门左转,前方10米上高速,我将View对象称为吃包子的家伙。它们在某一时刻可能想吃,也可能不想吃。

包子是怎样产生的我就不一一阐述了,在这,我们不讨论源码,你所需知道的就是,当你在屏幕上那么轻轻一碰的时候,Android的世界里就产生了一个包子,记住是一个,那些个move,down,up是多个包子的结合。当这个包子产生的时候,所有想吃包子的家伙全站在一棵树上,从上往下,依次是顶级的ViewGroup对象,子级的Layout对象,孙子级的button对象,之所以这么站着,是因为dispatchTouchEvent分发机制确定的,这帮家伙全抬着头,看着从天而降的包子,有部分流着哈喇子(想吃包子的家伙)。
所谓的拦截与分发,其本质就是将这个包子准确无误的送到想吃包子的家伙口中。

这帮家伙想吃包子使用的是onInterceptTouchEvent(事件的拦截),得到包子使用dispatchTouchEvent(事件的分发),消化包子使用的是 [ onTouch 或 onTouchEvent ](事件的处理)。

回到那颗树上,包子现在落在了最顶层的ViewGroup手里,它用onInterceptTouchEvent拿着包子,问题摆在它眼前,是吃呢还是分给子孙吃,onInterceptTouchEvent返回true,则表示,这货决定吃包子了,返回false,表示这货决定把包子留给子孙。

先说true的情况,这最老的祖宗觉得自己吃了一辈子的苦,不能再苦自己了,决意吃包子(true),手朝下一摆,别看了别看了,再看也没有包子吃,都散了吧。老祖宗捧着包子泪流满面,终于能吃一口热乎乎的包子了,三口并作两口的就把这包子给吞下去了,包子就这么来到了消化道,接下来就轮到onTouch 或 onTouchEvent 出场了,之所以是或,且听我慢慢道来。系统首先会判断该View是否实现了onTouchListener接口,实现的情况下,如有则执行onTouch方法,返回true,包子彻底被消化,返回false,包子的残渣进入onTouchEvent方法内部,若无,则直接执行onTouchEvent方法,也就是说只要有onTouch则一定会执行,而onTouchEvent的执行则是由onTouch是否存在及其返回值确定,在onTouchEvent内部会执行onClick方法,至此,包子的旅程结束了。

现在说false的情况,老祖宗仁慈啊,觉得自己七老八十了,再苦不能苦子孙,手一翻,把包子丢了下去,包子就落到了子级Layout手里,这儿子面临的抉择和它老爹是一样的,true请参照上面,false继续往下扔。

最不济的情况,一路false扔到底了,结果孙子级的button还不处理(onTouchEvent返回false),这下包子不乐意了,它很愤怒,开始了反弹,就到了父级的onTouchEvent,以此类推,该阶段下若某一级别onTouchEvent返回true,包子就被消化了,返回false,继续上弹,当弹到老祖宗手里的时候,老祖宗叹了口气,还是不想吃(返回fasle),则该包子被交由Activity的onTouchEvent处理。

至此,两条路包子都走到了头。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息