Android中父View和子view的点击事件的执行过程

Android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。 
一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP

当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是
ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?我只能很肯定的对你说不一定。呵呵,为什么呢?看看下面我的调查结果你
就明白了。

android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:

1)public boolean dispatchTouchEvent(MotionEvent ev)   这个方法用来分发TouchEvent

2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev)      这个方法用来处理TouchEvent

当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, 
TouchEvent最先到达最顶层 view的 dispatchTouchEvent,然后由  dispatchTouchEvent方法进行分发,

如果dispatchTouchEvent返回true,则交给这个view的onTouchEvent处理,

如果 dispatchTouchEvent返回 false,则交给这个 view的 interceptTouchEvent方法来决定是否要拦截这个事件,
如果 interceptTouchEvent返回 true,也就是拦截掉了,则交给它的onTouchEvent来处理,
如果 interceptTouchEvent返回 false,那么就传递给子 view,由子 view 的dispatchTouchEvent再来开始这个事件的分发。

如果事件传递到某一层的子 view的 onTouchEvent上了,这个方法返回了 false,那么这个事件会从这个 view往上传递,都是onTouchEvent来接收。
如果事件传递到某一层的子view的onTouchEvent上了,这个方法返回false,那么这个事件将不会向上传递了,又这个view拦截处理.
而如果传递到最上面的 onTouchEvent也返回 false的话,这个事件就会“消失”,而且接收不到下一次事件

onInterceptTouchEvent()用于处理事件并改变事件的传递方向。处理事件这个不用说了,你在函数内部编写代码处理就可以了。而决定传递方向的是返回值,返回为false时事件会传递给子控件的onInterceptTouchEvent();返回值为true时事件会传递给当前控件的onTouchEvent(),而不在传递给子控件,这就是所谓的Intercept(截断)。

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

本文源地址:http://www.cnblogs.com/rocky_yi/archive/2011/01/21/1941522.html# ,转载请注明出处!

<?xml version="1.0" encoding="utf-8"?>
<com.touchstudy.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <com.touchstudy.LayoutView2
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center">
       <com.touchstudy.MyTextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv"
            android:text="AB"
            android:textSize="40sp"
            android:textStyle="bold"
            android:background="#FFFFFF"
            android:textColor="#0000FF"/>
   </com.touchstudy.LayoutView2>
</com.touchstudy.LayoutView1>

在没有重写onInterceptTouchEvent()和onTouchEvent()的情况下(他们的返回值都是false), 对上面这个布局,MotionEvent事件的传递顺序如下:

当某个控件的onInterceptTouchEvent()返回值为true时,就会发生截断,事件被传到当前控件的onTouchEvent()。如我们将LayoutView2的onInterceptTouchEvent()返回值为true,则传递流程变成:

如果我们同时将LayoutView2的onInterceptTouchEvent()和onTouchEvent()设置成true,那么LayoutView2将消费被传递的事件,同时后续事件(如跟着ACTION_DOWN的ACTION_MOVE或者ACTION_UP)会直接传给LayoutView2的onTouchEvent(),不传给其他任何控件的任何函数。同时传递给子空间一个ACTION_CANCEL事件。传递流程变成(图中没有画出ACTION_CANCEL事件):

         

附SDK给出的说明:

·  You will receive the down event here.

·  The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.

·  For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target‘s onTouchEvent().

·  If you return true from here, you will not receive any following events: the target view will receive the same event but with the action ACTION_CANCEL, and all further events will be delivered to your onTouchEvent() method and no longer appear here.

时间: 2024-12-23 12:08:39

Android中父View和子view的点击事件的执行过程的相关文章

Android进阶笔记08:Android 中Activity、Window和View之间的关系

1. Android 中Activity.Window和View之间的关系(比喻): Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutInflater像剪刀,Xml配置像窗花图纸.  2. 详解:       Activity是Android应用程序的载体,允许用户在其上创建一个用户界面,并提供用户处理事件的API,如onKeyEvent, onTouchEvent等. 并维护应用程序的生命周期.Activity本身是个庞大的载体,

C#中父窗口和子窗口之间控件互操作实例

本文实例讲述了C#中父窗口和子窗口之间控件互操作的方法.分享给大家供大家参考.具体分析如下: 很多人都苦恼于如何在子窗体中操作主窗体上的控件,或者在主窗体中操作子窗体上的控件.相比较而言,后面稍微简单一些,只要在主窗体中创建子窗体的时候,保留所创建子窗体对象即可. 下面重点介绍前一种,目前常见的有两种方法,基本上大同小异: 第一种,在主窗体类中定义一个静态成员,来保存当前主窗体对象,例如: 代码如下: public static yourMainWindow pCurrentWin = null

angular 中父组件调用子组件的方法

angular中 父组件调用子组件的方法 -- 使用 @ViewChild 装饰器修饰子组件,获取方法,调用 除此之外 ViewChild 还可以获取 DOM ,操作 DOM , 详见: https://www.cnblogs.com/monkey-K/p/11567098.html 1. html 中使用 #var 方式标记 子组件 <div style="border: 1px solid red"> <p>子组件:</p>> <ap

Android中Toast如何在子线程中调用

当我们在应用的子线程中调用Toast的时候,我们会发现编译时并没有问题,但是当我们运行时就会出现如下错误 大专栏  Android中Toast如何在子线程中调用l/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="image"/> 通常我们都会认为此问题是因为在子线程中去更新UI导致的,其实不然,因为我们观察所抛出的log信息即可发现不是更新UI导致的,那么是什么原因导致的此问题呢 原文地址:https://www.cnblog

Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件

原文:Android项目实战(十六):QQ空间实现(一)-- 展示说说中的评论内容并有相应点击事件 大家都玩QQ空间客户端,对于每一个说说,我们都可以评论,那么,对于某一条评论: 白雪公主 回复 小矮人 : 你们好啊~ 我们来分析一下: 1.QQ空间允许我们 点击 回复人和被回复人的名字就可以进入对于用户的个人主页(即点击文字“白雪公主”/“小矮人”,就可以进入到这俩用户相应个人主页) 2.点击 回复的文字,就可以对回复人进行回复(即点击评论中回复的内容“你们好啊~”,便对弹出一个编辑框对回复人

jQuery之防止冒泡事件,冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件。

冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件. 下面是html代码部分: <body> <div id="content"> 外层div元素 <span>内层span元素</span> 外层div元素 </div> <div id="msg"></div> </body> 对应的jQuery代码如下: <script type="text/

android点击事件的分发过程

转载请注明出处 http://blog.csdn.net/a992036795/article/details/51698023 本文将讲述android点击事件的分发过程 我的上一篇文章讲述了android点击事件的来源,本文接着讲述当点击事件传输到Activity之后 分发的过程是什么样的. 上一篇文章链接: http://blog.csdn.net/a992036795/article/details/51690303 通过上一篇文章我们知道,事件最终会通过activity分发到Phone

scrollview添加手势 不影响子控件点击事件

给父视图添加手势,但是子视图的点击事件失效了,怎么办?我在写tableView 自定义cel中显示多张图片 可以左右滑动 我在cell里面放了一个collectionView, 点击tableViewCell 跳转到详情页 如果点的是collectionView里的第三张图片,则详情页直接滑到第三张 ,点击其他区域 从第一张开始. 当图片的少的时候 点击collectionView空白区域的时候,tableViewCell的点击代理方法不走,把collectionView的userInterac

Android 中几个重要的View

SurfaceView, GLSurfaceView, SurfaceTexture以及TextureView是Android当中名字比较绕,关系又比较密切的几个类.本文基于Android 5.0(Lollipop)的代码理一下它们的基本原理,联系与区别. SurfaceView从Android 1.0(API level 1)时就有 .它继承自类View,因此它本质上是一个View.但与普通View不同的是,它有自己的Surface.我们知道,一般的Activity包含的多个View会组成Vi