`

浅谈onInterceptTouchEvent、onTouchEvent与onTouch

阅读更多
一、onTouch

onTouch是View中OnTouchListener接口中的方法,处理View及其子类被touch是的事件处理。当然,前提是touch时间能够传递到指定的view。Q1:为什么会传递不到呢?

 
 /**
   * Interface definition for a callback to be invoked when a touch event is
   * dispatched to this view. The callback will be invoked before the touch
   * event is given to the view.
   */
   public interface OnTouchListener {
       /**
         * Called when a touch event is dispatched to a view. This allows listeners to
         * get a chance to respond before the target view.
         *
         * @param v The view the touch event has been dispatched to.
         * @param event The MotionEvent object containing full information about
         *        the event.
         * @return True if the listener has consumed the event, false otherwise.
         */
        boolean onTouch(View v, MotionEvent event);
   }

二、onTouchEvent

onTouchEvent同样也是在view中定义的一个方法。处理传递到view 的手势事件。手势事件类型包括ACTION_DOWN,ACTION_MOVE,ACTION_UP,ACTION_CANCEL四种事件。

  
/**
    * Implement this method to handle touch screen motion events.
    *
    * @param event The motion event.
    * @return True if the event was handled, false otherwise.
    */
   public boolean onTouchEvent(MotionEvent event) {
    ……
    ……
  }

一旦onTouchEvent方法被调用,并返回true则这个手势事件就结束了,并不会向下传递到子控件。Q2:onTouchEvent什么时候被调用呢?

三、onInterceptTouchEvent

onInterceptTouchEvent是在ViewGroup里面定义的。Android中的layout布局类一般都是继承此类的。onInterceptTouchEvent是用于拦截手势事件的,每个手势事件都会先调用onInterceptTouchEvent。

 
 public boolean onInterceptTouchEvent(MotionEvent ev) {
           return false;
   }

此方法返回false,则手势事件会向子控件传递;返回true,则调用onTouchEvent方法。

onInterceptTouchEvent()用于处理事件并改变事件的传递方向。返回值为false时事件会传递给子控件的onInterceptTouchEvent();
返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件,这就是所谓的Intercept(截断)。

onTouchEvent() 用于处理事件,返回值决定当前控件是否消费(consume)了这个事件。可能你要问是否消费了又区别吗,反正我已经针对事件编写了处理代码?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。

由于onInterceptTouchEvent()的机制比较复杂,上面的说明写的也比较复杂,总结一下,基本的规则是:
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()处理。


http://2528.iteye.com/blog/1056731

onInterceptTouchEvent和onTouchEvent调用关系详解
http://www.eoeandroid.com/thread-178659-1-1.html
return true和return false,代表的是是否消费完该事件,也就是该事件是否会继续传递给下层或者上层组件继续处理。return true代表消费完不会继续传递,return false代表没有消费完将会继续传递。

如果没有onInterceptTouchEvent,只考虑onTouchEvent的话,比较容易分析和理解。假如有三层布局结构,linearLayout1,linearLayout2,textView,从前到后是包含的关系。那么下面分情况说明。
1.如果它们的onTouchEvent都返回false的话,DOWN事件会自上而下(textView位于最上层)依次传递,最终都没有消费完此事件,都只会进入onTouchEvent方法一次并且MotionEvent的action为MotionEvent.ACTION_DOWN,move和up等事件不会继续处理。
2.如果textView的onTouchEvent返回true,表示textView消费了此事件,不会传给父组件linearLayout2和linearLayout1了,并且还会继续处理move和up等事件。
3.linearLayout2和linearLayout1的onTouchEvent返回true和上面的情况一样,都不会继续传给父容器而且本身继续处理move和up等事件。
OK,这种情况还是比较容易理解的。

下面加入onInterceptTouchEvent。
onInterceptTouchEvent只有ViewGroup才会有,用于在进入自身onTouchEvent或者子组件onTouchEvent之前处理事件。注意onTouch是自上而下传递,而onInterceptTouch却是由下而上传递的。来了一个DOWN事件,首先进入的必然是最底层的viewGroup的onInterceptTouchEvent方法,然后根据return的值进入自身或者子组件的onTouch事件,当然如果子组件也是viewgroup的话,在进入子组件的onTouch之前也会进入子组件的onInterceptTouchEvent方法。
下面也分几种情况介绍:
1.当onInterceptTouchEvent返回false时,表示没有消费完此事件,会继续传递个子组件的onTouch继续处理。注意这种情况不会就不会传递给这个ViewGroup自身的onTouch事件处理了。这和onTouch如果返回false,后续的move、up等事件都不会继续处理了可以做同样理解。
2.当onInterceptTouchEvent返回true时,表示消费完此事件,或者说将在此组件上消费该事件。这种情况该事件会传递给ViewGroup自身的onTouch事件去处理,而不会传递给子组件的onTouch方法了。
由此可以总结,onInterceptTouchEvent返回值只是决定了是要把事件传递给自身的onTouch事件还是传递给子组件的onTouch事件。返回false表示没有消费完将传递个子组件的onTouch方法,返回true表示自身消费此事件,将传递给自身的onTouch方法而不会传递给子组件的onTouch方法了。
分享到:
评论
4 楼 yangmaolinpl 2017-03-02  
希望有表例子更好。。。,不过也看明白了。
3 楼 naifei1234 2013-10-15  
                         
2 楼 lenomon 2012-04-02  
1 楼 进阶兄 2011-09-06  
谢谢,获益匪浅

相关推荐

    onInterceptTouchEvent和onTouchEvent调用关系详解

    `onInterceptTouchEvent`和`onTouchEvent`是两个关键的方法,它们协同工作以处理触摸屏幕的动作。这篇文章将深入探讨这两个方法的调用关系及其在Android事件分发机制中的作用。 首先,我们要理解Android的事件分发...

    安卓onTouchEvent上下左右滑动事件

    在Android开发中,触摸事件是用户与应用交互的重要方式,特别是在移动设备上。`onTouchEvent`是处理触摸事件的主要方法,它可以捕捉用户的点击、滑动等手势。本篇将详细讲解如何通过重写`onTouchEvent`来实现上下...

    onclick与ontouch和scroll监听冲突的解决方法

    总之,解决`onclick`、`ontouch`和`scroll`监听冲突的关键在于理解Android的事件分发机制,并灵活运用`onInterceptTouchEvent`和`onTouchEvent`来控制事件处理。通过合理地判断和拦截事件,可以实现流畅且无冲突的...

    Android onTouchEvent事件中onTouch方法返回值(介绍)

    本文将详细介绍`onTouchEvent`中`onTouch`方法的返回值及其影响。 `onTouchEvent` 方法接收两个参数:一个`View`对象(通常是你希望监听触摸事件的视图)和一个`MotionEvent`对象,后者包含了触摸事件的所有详细...

    Android onTouch事件传递机制

    开发者可以通过重写`onInterceptTouchEvent`和`onTouchEvent`来定制ViewPager的行为,例如添加自定义的滑动手势。 了解并掌握`onTouch`事件传递机制对于优化Android应用的用户交互体验至关重要。理解事件分发链、...

    dispatch、onIntercept、onTouch三者对MotionEvent的分发、拦截机制Demo

    Title : dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三者对MotionEvent的分发、拦截机制分析 Author: yaong Category:自己做的Demo Tips : 三个自定义View,依次嵌套,并各自覆写拦截、监听方法,通过...

    onTouch测试

    在Android开发中,触摸事件是用户与应用交互的重要方式,`onTouch`是处理这些触摸事件的主要接口之一。本文将深入探讨`onTouch`事件传递机制,并通过`TestActivity`这个示例来解析其实现。 Android系统使用一个事件...

    onTouch demo

    `onTouch`事件是Android系统提供的一种处理触摸屏幕事件的方式,它允许开发者精确地控制用户与界面元素的交互。本示例"onTouch demo"旨在帮助开发者理解并解决常见的触摸事件冲突问题,并在面试中能够清晰地阐述`...

    android click 和onTouch 事件处理机制.

    如果在`ACTION_DOWN`事件中,`onInterceptTouchEvent`返回`true`,那么后续的事件将直接传递给`onTouchEvent`,而不会再次经过父视图的拦截。 接下来,我们讨论`onClick`和`onLongClick`。这两个方法是与触摸事件...

    Android中丰富多彩的onTouch事件.rar

    在Android开发中,触摸事件是用户与应用交互的重要方式,`onTouch`事件处理机制是这一过程中的核心。本文将深入探讨`onTouch`事件在Android中的应用,以及如何利用它来实现丰富多彩的用户交互。 一、`MotionEvent`...

    Android中touch事件传递测试demo

    onInterceptTouchEvent和onTouchEvent调用时序详解 测试demo 详细介绍请移步:http://blog.csdn.net/yiranxinshou/article/details/9201833

    两个重叠组件触摸事件冲突解决

    4. **自定义ViewGroup**:如果组件嵌套在自定义的ViewGroup中,我们可以在ViewGroup的`onInterceptTouchEvent()`方法中决定事件是否应该被拦截并分发给特定的子View。通过这种方式,我们可以控制事件流,避免冲突。 ...

    ViewEventDispatch.zip

    `onTouch()`是`View.OnTouchListener`接口中的方法,与`onTouchEvent()`类似,用于监听触摸事件。开发者可以设置`OnTouchListener`为View,以在特定View上捕获触摸事件。`onTouch()`的返回值同样决定事件是否被消费...

    Android从源码的角度彻底理解事件分发机制的解析(上)

    首先,我们需要了解事件分发涉及的主要方法:`dispatchTouchEvent()`、`onTouchEvent()` 和 `onInterceptTouchEvent()`。当用户在屏幕上触摸时,系统会生成一个MotionEvent,然后通过事件分发机制将这个事件传递给...

    view+viewPager 事件传递机制

    首页是用来测试onTouch与onClick执行顺序的,有部分手机在真机调试的时候,不输出log.d,大家可以修改为log.e 输出。 view事件传递机制中,ViewEventActivty这个类 通过输出,可以知道,先执行父控件的dispatch事件,...

    android面试题目整理

    如果`onInterceptTouchEvent`返回true,事件将在当前ViewGroup中处理,调用`onTouchEvent`方法。如果返回false,事件将继续传递给子View。如果子View是另一个ViewGroup,事件分发过程会在子ViewGroup中重复;如果是...

    完全理解android事件分发机制

    在View中其间会调用onTouchEvent(),在ViewGroup中其间会调用onInterceptTouchEvent()和onTouchEvent()。 **onInterceptTouchEvent():**这个函数是事件拦截函数,是ViewGroup才有的函数。

    android面试

    - `View`的`onTouchEvent`方法是否执行与其`OnTouchListener`回调方法`onTouch`的返回值密切相关。若`onTouch`返回`false`,则`onTouchEvent`方法将被执行。 #### 三、总结 理解Android中的事件分发机制对于编写...

    Android事件的分发机制详解

    在分发过程中,`dispatchTouchEvent()` 负责将事件传给子View,`onInterceptTouchEvent()` 允许 ViewGroup 在事件到达具体子View之前拦截事件,而 `onTouchEvent()` 是处理实际的触摸事件。 在上述示例代码中,一个...

    android事件的分发

    `OnTouchDemo02`是一个典型的事件处理示例,它可能包含了一个自定义的View或者Activity,展示了如何使用`onTouchEvent`和`onInterceptTouchEvent`方法来处理触摸事件。在这个示例中,开发者可能会覆盖这两个方法,...

Global site tag (gtag.js) - Google Analytics