Android:ViewGroup事件分发机制

关于ViewGroup事件分发机制的文章已经有很多了,推荐郭霖和鸿洋的两篇文章,

http://blog.csdn.net/guolin_blog/article/details/9153747

http://blog.csdn.net/lmj623565791/article/details/39102591

结合他们写的,自己简单总结一下,可能只适用个人。


流程

在上一篇文章中讲到,当你操作一个控件时,不管是按下、移动、抬起,在事件中途未被消费的情况下系统会按照View.dispatchTouchEvent -> OnTouchListener.onTouch -> View.onTouchEvent分发下去。事实上,事件最先分发到的是ViewGroupdispatchTouchEvent、然后分发到onInterceptTouchEvent方法,而第二个方法顾名思义就是用来拦截消费事件的。代码如下,默认就是不拦截。

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

接下来看一下ViewGroup.dispatchTouchEvent方法,源码比较长为了不占篇幅,可以直接在上面的文章看。观察源码可以发现,当按下控件时事件会分发到onInterceptTouchEvent方法中,而默认这个方法是返回false,然后系统通过坐标的计算得出当前按的控件是否是ViewGroup里面的子View,如果是,将事件分发给这个子View,也就是按照View.dispatchTouchEvent -> OnTouchListener.onTouch -> View.onTouchEvent**,并且将这个子View赋给target记录下来,方便后面控件移动、抬起操作的识别。如果不是,则会有如下代码

if (target == null) {
        ev.setLocation(xf, yf);
        if ((mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {
            ev.setAction(MotionEvent.ACTION_CANCEL);
            mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
        }
        return super.dispatchTouchEvent(ev);
    }  

可以看到如果点击的不是子View,则会把事件分发到super.dispatchTouchEvent方法,而ViewGroup的父类正是View,所以可以这么理解,点击一个控件时,先在ViewGruop.dispatchTouchEvent里面判断点击的是不是子View,是则按照View的事件分发机制分发下去,否则把ViewGroup本身作为一个View,按照View的事件分发机制分发下去。而常见的ViewGroup无非就是一些布局还有AdapterView等。


小结

  • 如果ViewGroup可以找到子View,就将事件分发给子View,否则自己作为一个View分发事件。
  • 通过重写ViewGroup.onInterceptTouchEvent方法可以实现对不同动作的事件的拦截,由ViewGroup自身处理事件。

分析两篇文章,我们一般都不需要重写ViewGroup和View的dispatchTouchEvent方法和View.onTouchEvent方法,程序员需要关心的是ViewGroup.onInterceptTouchEventonTouch,前者是实现ViewGroup对子View事件的拦截,后者是实现View分发流程时onTouch方法对onTouchEvent方法的拦截,而onTouchEvent则是实现判断onLongClickonClick等动作的逻辑的。

ViewGroup.onInterceptTouchEvent默认返回false,则点击到子View时会把事件分发给子View,onTouch返回false或者不存在OnTouchListener时,则会把事件分发到onTouchEventonLongClick返回false或者不存在OnLongClickListener时,事件才有可能传递给onClick方法

时间: 2024-10-12 23:41:03

Android:ViewGroup事件分发机制的相关文章

Android ViewGroup事件分发机制

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39102591,本文出自[张鸿洋的博客] 上一篇已经完整的解析了Android View的事件分发机制,今天给大家代码ViewGroup事件分发的源码解析~~凡是自定义ViewGroup实现各种滑动效果的,不可避免的会出现很多事件的冲突,对ViewGroup事件分发机制的了解,也有益于大家了解冲突产生的原因,以及对冲突进行处理~ 1.案例 首先我们接着上一篇的代码,在代码中添加一

(转)Android ViewGroup事件分发机制

3.关于拦截 1.如何拦截 上面的总结都是基于:如果没有拦截:那么如何拦截呢? 复写ViewGroup的onInterceptTouchEvent方法: [java] view plain copy @Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: //如果你觉得需

Android View 事件分发机制 源码解析 (上)

一直想写事件分发机制的文章,不管咋样,也得自己研究下事件分发的源码,写出心得~ 首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个MyButton继承Button,然后把跟事件传播有关的方法进行复写,然后添加上日志~ MyButton [java] view plain copy package com.example.zhy_event03; import android.content.Context; import andr

Android View 事件分发机制源码详解(View篇)

前言 在Android View 事件分发机制源码详解(ViewGroup篇)一文中,主要对ViewGroup#dispatchTouchEvent的源码做了相应的解析,其中说到在ViewGroup把事件传递给子View的时候,会调用子View的dispatchTouchEvent,这时分两种情况,如果子View也是一个ViewGroup那么再执行同样的流程继续把事件分发下去,即调用ViewGroup#dispatchTouchEvent:如果子View只是单纯的一个View,那么调用的是Vie

Android View框架总结(八)ViewGroup事件分发机制

请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52298780 上篇分析了View的事件分发流程,留了一个问题:如果上面的EventButton继承TextView的话,按下抬起,会有一个现象,我可以告诉大家现象:就是只有dispatchTouchEvent ACTION_DOWN,onTouch ACTION_DOWN,onTouchEvent ACTION_DOWN这三个,你移动,或者抬起,是没有MOVE,或者

Android Touch事件分发机制学习

Android  事件分发机制 ViewGroup dispatchTouchEvent 返回true dispatchTouchEvent: Activity ACTION_DOWN MyrelativeLayout dispatchTouchEvent: ACTION_DOWN dispatchTouchEvent: Activity ACTION_UP MyrelativeLayout dispatchTouchEvent: ACTION_UP ViewGroup自己在dispatchTo

Android触摸事件分发机制

Android中的事件分为按键事件和触摸事件,这里对触摸事件进行阐述.Touch事件是由一个ACTION_DOWN,n个ACTION_MOVE,一个ACTION_UP组成onClick,onLongClick,onScroll等事件.Android中的控件都是继承View这个基类的,而控件分为两种:一种是继承View不能包含其他控件的控件:一种是继承ViewGroup可以包含其他控件的控件,暂且称为容器控件,比如ListView,GridView,LinearLayout等. 这里先对几个函数讲

Android View 事件分发机制梳理

View初探 一直以来对View的事件分发机制很晕,今天就在这里梳理一下 MyView 首先继承View类,自定义一个MyView.并在初始化时打印View类是否可点击,这里从View点击事件分发的角度出发,所以不考虑绘制,测量相关方法的实现. public class MyView extends View { String TAG = "Activity"; public MyView(Context context) { super(context); init(); } pub

Android View事件分发机制

最近在开发中遇到view滑动冲突的问题,由于一开始就知道这个问题与view事件分发有关,之后在网上看了几篇关于事件分发的资料后,开发中遇到的问题很快便得到解决. 在这里总结一下我对view事件分发的理解. 首先,看下事件分发流程图: Button事件演示 在对view的事件分发机制进行分析前,我们可以通过一个demo看看Button的事件处理的流程. 在布局文件中添加一个button控件,然后在代码中实现Button的setOnClickListener和setOnTouchListener方法