Android Input System分析(四)--应用层

来源:互联网 发布:如何在淘宝卖高仿鞋 编辑:程序博客网 时间:2024/05/29 18:58

本来在讲应用层的消息传递之前,应该讲一下app framework层的消息处理,但实际上这部分的工作并不多,大部分的消息都是直接传递给APP,由APP来消费用户的操作,这个也是软件设计的本意--以用户为中心。在Phonewindowmanager中只是针对home键、back键、menu键等系统级的按键做了拦截并处理。

在开始之前,我们先看个故事,故事不是我编的,网上就有。

--------------------------------------------------------------------------------------------------------------

话说一家软件公司,来一个任务,分派给了开发经理去完成:
开发经理拿到,看了一下,感觉好简单,于是
开发经理:分派给了开发组长
开发组长:分派给了自己组员(程序员)
程序员:分派给了自己带的实习生。
实习生:好苦逼,无法分派,怎么办啊?只能自己干了
但是实习生能不能做好,有两种情况了。
情况一:
实习生:经过一段时间的研究,琢磨,熬夜,奋斗,死敲,皇天不负有心人啊,完成了。
后来又来一个类似的任务,也按着这样传递下去了(开发经理->开发组长->程序员->实习生),又有实习生完成了。
情况二:
实习生:经过一段时间的研究,琢磨,就是毫无头绪,无法完成,只能求教师傅(程序员)了。
程序员:啊,我怎么没留意就给实习生搞了,这任务好难啊,自己研究下,也没有头绪,没办法只能请求组长了。
开发组长:这任务不难啊,怎么我底下的人都不会了,没办法,只能自己搞了,经过,一段时间,完成了,感想,以后要是又有跟这个很类似的任务,我就自己弄了,不给他们弄了。
后来又来一个类似的任务,传递是这样的
开发经理:分派给开发组长
开发组长:啊,又是跟着上一个很类似的任务,我自己弄吧,没过多久也完成了!
----------------------------------------------------------------------------------------------------------------
Android touch 事件

★事件构成

        在Android中,事件主要包括点按、长按、拖拽、滑动等,点按又包括单击和双击,另外还包括单指操作和多指操作。所有这些都构成了Android中的事件响应。总的来说,所有的事件都由如下三个部分作为基础:

★按下(ACTION_DOWN)
★移动(ACTION_MOVE)
★抬起(ACTION_UP

 所有的操作事件首先必须执行的是按下操作(ACTIONDOWN),之后所有的操作都是以按下操作作为前提,当按下操作完成后,接下来可能是一段移动(ACTIONMOVE)然后抬起(ACTION_UP),或者是按下操作执行完成后没有移动就直接抬起。这一系列的动作在Android中都可以进行控制。


★嵌套布局事件传递


·所有的视图都继承于View
·ViewGroup也继承于View
·所有的UI控件例如Button、TextView都是继承于View
·所有的布局控件例如RelativeLayout、容器控件例如ListView都是继承于ViewGroup
·事件操作主要就是发生在View和ViewGroup之间

dispatchTouchEvent方法用于事件的分发,Android中所有的事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。返回true表示不继续分发,事件没有被消费。返回false则继续往下分发,如果是ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件。
★事件处理
onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View。
★事件拦截
onInterceptTouchEvent是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身onTouchEvent方法用于事件的处理,返回true表示消费处理当前事件,返回false则不处理,交给子控件进行继续分发。

Android touch 事件处理举例:

例子1:

step1:
触摸事件先被LLinearLayout拦截到(onInterceptTouchEvent),该方法返回值为false,接着就将Touch事件传递给LView,LView的onTouchEvent响应了此次触摸事件,并且也返回false;然后Touch事件再传递给LLinearLayout的onTouchEvent进行处理;

从上面我们可以简单的看出,Touch事件先被LLinearLayout拦截到,然后传递给LView,LView执行onTouchEvent处理逻辑;然后LLinearLayout再执行自己的onTouchEvent处理逻辑;

step2:
将上面LLinearLayout的onInterceptTouchEvent方法返回值改为true。可以看到消息没有传递到LView。

ViewGroup里面的onInterceptTouchEvent返回值,返回true表示拦截Touch事件,不再将Touch事件传递给ViewGroup里面的子View;


step3: 
回到step1,将LView中onTouchEvent返回值改为true,再次运行程序,手指从屏幕右滑到左



可以看出,LView的onTouchEvent返回值为true时,LView的触摸事件从DOWN传递到了MOVE,再传递到UP;当然,整个过程都是先由LLinearLayout的onInterceptTouchEvent先接收到Touch事件,在这里,并没有拦截Touch事件,而是将Touch事件传递给子View;细心的朋友可能会发现,在这里,并没有执行到LLinearLayout的onTouchEvent方法,why?其实是因为LView的onTouchEvent事件返回了true,表示处理消耗了此事件,不再继续传递,也就不执行到LLinearLayout的onTouchEvent方法;


结论:View的onTouchEvent返回值表示是否将继续传递Touch事件,比如如果返回true,触摸形态将会从DOWN传递到MOVE再到UP(这里这个说法其实不严谨,这里指的是整个onTouchEvent方法返回值都是true,而没有分段返回,比如在MOVE形态时返回了false);

原创粉丝点击