Samoy的小窝

千里之行,始于足下 万行代码,始于指下

一只默默工作的程序猿


欢迎光临Samoy的小窝

Android触摸事件传递机制

触摸事件的类型

触摸事件对应的MotionEvent类型,事件类型主要有如下三种:

  • ACTION_DOWN:用户手指按下的操作,一个按下操作标志着一次触摸事件的开始.
  • ACTION_MOVE:用户按压屏幕后,在松开之前,如果移动的距离超过一定的阈值,那么就会被判定为ACTION_MOVE操作,一般情况下,手指的轻微移动都会触发这一事件.
  • ACTION_UP:用户手指离开屏幕的操作,这一操作标志一个事件的结束.

    事件传递的三个阶段

  • 分发(Dispatch):事件的分发对应着dispatchTouchEvent方法,在Android系统中,所有的触摸事件都是通过这个方法来分发的,方法的原型如下:
    public boolean dispatchTouchEvent(MotionEvent ev)
    

    在这个方法中,根据当前视图的具体实现逻辑,来决定是直接消费事件还是将这个事件继续传递下去,方法返回值为true表示当前事件被消费掉,返回值为super.dispatchEvent表示继续分发该事件.如果当前视图是ViewGroup及其子类,则会调用onInterceptTouchEvent方法判定是否拦截该事件.

  • 拦截(Intercept):事件的拦截对应着OnInterceptEvent方法,这个方法只在ViewGroup及其子类才会存在,在View和Activity中是不存在的。方法的原型如下:
    public boolean onInterceptTouchEvent(MontionEvent ev) 
    

    同理,这个方法也是通过返回的布尔值来决定是否拦截对应的事件,根据具体的实现逻辑,返回true表示拦截该事件,不再分发给子视图,同时交由给自身的onTouchEvent方法消费该事件,返回false或者super onInterceptTouchEvent表示不对该事件进行拦截,需要传递给子视图。

  • 消费(Consume):事件的消费对应着onTouchEvent方法,方法原型如下:
    public boolean onTouchEvent(MotionEvent event)
    

    该方法返回值为true表示当前视图可以处理该事件,事件将不会向上传递给父视图;返回false表示当前视图不处理这个事件,事件会被传递给父视图的onTouchEvent方法。 在Android系统中,拥有事件传递处理能力的类有以下三种:

  • Activity:拥有dispatchTouchEventonTouchEvent两个方法。
  • ViewGroup:拥有dispatchEventonInterceptTouchEventonTouchEvent三个方法。
  • View:拥有dispatchTouchEventonTouchEvent两个方法。

    View的事件传递机制

  • 触摸事件的传递流程是人dispatchTouchEvent方法开始的,如果不进行人为干预(也就是返回父级的同名函数),则事件将会依照嵌套层次从外层向外层传递,到达最内层的View时,就由它的onTouchEvent方法处理,该方法若能够消费该事件,则返回true,如果处理不了,则返回false,将事件向外层传递,并由外层View的onTouchEvent方法进行处理,依此类推。
  • 如果事件在向内层传递的过程中由于人为干预,事件处理函数返回true,则会导致事件提前被消费掉,内层View不会接收到该事件。
  • View控件的事件触发顺序是先执行onTouch方法,在最后才执行onClick方法。如果onTouch返回true,则事件不会传递,最后也不会调用onClick方法;如果onTouch返回false,则事件继续传递。

    ViewGroup事件传递机制

  • 触摸事件的传递顺序是由Activity传递给ViewGroup,再由ViewGroup传递给它的子View。
  • ViewGroup通过onInterceptTouchView方法对事件进行拦截,如果该方法返回true,则事件并不会传递给子View,如果返回false或者super.onInterceptTouchEvent,则事件会继续传递给子View。
  • 在子View中对事件进行消费后,ViewGroup将不会接收到任何事件。
最近的文章

如何优雅的关闭VMWare虚拟机

VMWare(以下简称VM)虚拟机大家应该都用过,但是关闭VM后,我们会发现托盘仍然有VM的图标,对于强迫症来说很不爽,因为此时VM并没有彻底关闭,那么如何让VM彻底关闭呢。下面介绍两种方法:第一种:通用法 首先我们打开VM,然后编辑->首选项,界面如下:然后将显示托盘图标选择为“从不”。 然后我们打开任务管理器,将VMWare开头的进程关闭,如图所示:如此即可。那么有没有更好的方法不用这么麻烦呢,当然有,接下来我们介绍第二种方法。第二种:脚本法首先我们在桌面新建文本文档,然后将...…

更早的文章

利用抓包工具获取今日头条的文章信息

安装Windows推荐使用Fiddler,Mac推荐使用Charles。两个工具均属于收费应用,请自行百度下载地址。由于笔者使用的是Mac,接下来以Charles为例来做说明,Fiddler与其大同小异。Charles配置首先我们打开Charles,界面如下:此时没有任何信息,接下来我们点击Proxy->Proxy Settings,界面如下:然后我们来找到电脑的IP地址,命令行输入ifconfig或者在系统偏好设置->网络中查看iPhone配置切记:先将手机上开启的VPN关掉...…