Android Touch 手势触摸原理

来源:互联网 发布:java maven 项目打包 编辑:程序博客网 时间:2024/06/08 11:49

Android Touch 手势触摸原理

在自定义View的时候,我们可能需要实现一些滑动、拖动的功能,在实现这些功能之前,我们有必要先了解Android Touch相关的内容,特别是Android Touch的分发原理。


Android Touch 原理

当我们触摸屏幕时候,会产生下面几个原子性的Touch事件:

  • 按下( MotionEvent.ACTION_DOWN)
  • 移动( MotionEvent.ACTION_MOVE)
  • 弹起( MotionEvent.ACTION_UP)

这里为了将它们与点击、双击等触摸事件分开来,我们在这里将其称之为原子Touch事件。其中按下与弹起是必定会产生的事件,在两个动作之间还有可能产生不定数量的移动事件,需要注意的是,这三个事件是有顺序的:按下-移动-弹起。由这三个原子Touch事件再加上一些逻辑判断,才构成了点击、双击等常见的事件。那么这些Touch事件会经由哪些界面元素,又是怎么在界面分发的呢?
首先,我们看看会接收到Touch事件经过的主要方法:

  • Activity.onTouchEvent(MotionEvent event)
  • ViewGroup.onInterceptTouchEvent(MotionEvent ev)
  • ViewGroup.onTouchEvent(MotionEvent event) (这里实质就是View.onTouchEvent(MotionEvent event))
  • View.onTouchEvent(MotionEvent event)

Touch事件会在上面几个方法中传递,并且在Android Touch事件传递分发的过程中,有一个很重要的概念,那就是“消费”,意思就是如果某个Touch事件被消费了,那么这个事件就会消失,不会再传递或者分发给谁了。在我们描述分发原理之前,我们需要假定当前的布局为ViewGroup包含View。由于Android Touch的分发流程会根据消费和拦截情况进行,所以下面我们看看消费和拦截产生的影响:

  • 消费:
    • 当onTouchEvent(MotionEvent) 方法返回值为true,标志着该事件会被消费,返回false,说明该事件不被消费。一旦被消费后,该事件就不再被分发,如果ViewGroup和View都不消费该事件,那么最终会返回给Activity。
    • 只有当我们消费了按下事件,才会接收到移动&弹起事件。当ViewGroup消费了按下事件,那么View不会接收到任何事件,事件传递会止于ViewGroup那一层。当View消费了按下事件,这时候后续事件会经过ViewGroup才到View。默认情况下,ViewGroup与View不会消费按下事件,因此它们也不会接收到后续的移动&弹起事件。
  • 拦截:
    • ViewGroup与View之间存在着一个拦截机制。对于ViewGroup而言,拦截后该事件会转交给ViewGroup.onTouchEvent(MotionEvent),将不会再传递给View.对于View而言,只要一旦事件被ViewGroup拦截,那么View将不会接收到。

综合上面消费&拦截,下面是各种情况下的事件分发,基本涵盖了Android事件的正常分发流程:

按下事件分发流程

按下事件分发原理

ViewGroup拦截消费按下事件后的流程

这里写图片描述

View消费按下事件后的流程

这里写图片描述

有没有发现View消费按下事件后的其他事件分发,跟按下事件的分发流程十分相似,只是当View.onTouchEvent()不消费的时候,才略有不同。
以上三个流程图基本涵盖了Android Touch事件的正常分发过程。通过上面图片我们可以看出,事件是由ViewGroup分发到View的,如果我们需要改变这个分发顺序,跳过ViewGroup,直接获取触摸事件,那么我们可以通过以下代码片实现:

    public boolean onTouchEvent(MotionEvent event) {        //调用这个方法之后,事件将不再通过ViewGroup.        getParent().requestDisallowInterceptTouchEvent(true);       // ...       return true;    }
0 0
原创粉丝点击