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 booleandispatchTouchEvent(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.

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

  1. 事件之父View和子view的点击事件的执行过程

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

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

    1. Android 中Activity.Window和View之间的关系(比喻): Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图) LayoutI ...

  3. React中父组件与子组件之间的数据传递和标准化的思考

    React中父组件与子组件之间的数据传递的的实现大家都可以轻易做到,但对比很多人的实现方法,总是会有或多或少的差异.在一个团队中,这种实现的差异体现了每个人各自的理解的不同,但是反过来思考,一个团队用 ...

  4. artdialog4.1.7 中父页面给子页面传值

    artdialog4.1.7中父页面给子页面传值时看了一些网友的解决方法: 在父页面声明全局变量 var returnValue=“ ”,子页面用art.dialog.opener.returnVal ...

  5. Vue中父组件向子组件传值

    Vue中父组件向子组件传值 相关Html: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

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

    冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件. 下面是html代码部分: <body> <div id="content"> 外层div元素 ...

  7. ExpandableListView实现子Item的点击事件

    在继承的BaseExpandableListAdapter的ExpandableListView的Adapter中,重写以下方法 @Override public boolean isChildSel ...

  8. Android Touch事件之一:Touch事件在父ViewGroup和子View之间的传递篇

    2015-11-26 17:00:22 前言:Android的Touch事件传递和View的实现紧密相连,因此理解Touch事件的传递,有助于我们更好的理解View的工作原理. 1. 几个重要的方法: ...

  9. View事件传递之父View和子View之间的那点事

    Android事件传递流程在网上可以找到很多资料,FrameWork层输入事件和消费事件,可以参考: Touch事件派发过程详解 这篇blog阐述了底层是如何处理屏幕输,并往上传递的.Touch事件传 ...

随机推荐

  1. 【leetcode】994. Rotting Oranges

    题目如下: In a given grid, each cell can have one of three values: the value 0 representing an empty cel ...

  2. Cisco基础(六):配置目前网络环境、项目阶段练习

    一.配置目前网络环境 目标: 一家新创建的IT公司,公司位于北京有80多台服务器 目前网络环境使用技术,通过端口映射技术将web服务器发布给Internet: 三层交换:汇聚接入层交换机 默认路由:实 ...

  3. <Jmeter入门不放弃>之<2.常用功能>

    大家这里参考学习的时候,我就不在这里配截图了,因为需要你打开工具根据文档自己去找,才有印象,大家一定要启动JMeter!跟着理解操作 一.测试计划 用来描述一个性能测试,所有内容都是基于这个计划,这谁 ...

  4. (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片

    转:http://blog.csdn.net/junzia/article/details/52842816 前面几篇博客,我们将了Android中利用OpenGL ES 2.0绘制各种形体,并在上一 ...

  5. 集合类不安全之ArrayList

    1. 不安全的ArrayList 大家都知道ArrayList线程不安全,怎么个不安全法呢?上代码: public class ContainerNotSafeDemo { public static ...

  6. 56、salesforce学习笔记(三)

    Date类型 Datetime nowDatetime = Datetime.now(); Datetime datetime1 = Datetime.newInstance(2015,3,1,13, ...

  7. mybatis的sqlprovider用法扩展自定义sql

    SqlProvider使用 public class MemberRewardSqlProvider { private static final Logger log = LoggerFactory ...

  8. Ubuntu下实现Nginx+Tomcat实现负载均衡

    先说一下为什么写这个文章,在性能测试过程中,我们可能会关注很多指标,比如CPU.IO.网络.磁盘等,通过这些指标大致可以判断哪个环节遇到了性能瓶颈,但是当这些指标无法判断出性能瓶颈时,我们可能就需要对 ...

  9. bash arithmatic

    Arithmetic in bash is done with $ and double parentheses: echo "$(($num1+$num2))" Or $ and ...

  10. spark复习总结02

    1.spark执行原理图 spark程序启动后创建sparkContext作为程序的入口,sparkContext可以与不同类的集群资源管理器(Cluster Manager)进行通信,从而获得程序运 ...