Android笔记:触摸事件的分析与总结----TouchEvent处理机制

   其他相关博文:

   Android笔记:触摸事件的分析与总结----MotionEvent对象

   Android笔记:触摸事件的分析与总结----TouchEvent处理机制

Android中的事件类型分为按键事件和屏幕触摸事件。TouchEvent是屏幕触摸事件的基础事件,要深入了解屏幕触摸事件的处理机制,就必须掌握TouchEvent在整个触摸事件中的转移和处理过程。此处将对TouchEvent处理机制的学习做个小小的总结和备记。

当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是 ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?

这问题涉及到与每个View或者ViewGroup的子类都具有的三个和TouchEvent处理密切相关的方法:

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

2)onInterceptTouchEvent(MotionEvent ev)  这个方法用来拦截TouchEvent

3)onTouchEvent(MotionEvent ev)           这个方法用来处理TouchEvent

其中view类和Activity中都有dispatchTouchEvent()和onTouchEvent()两个方法。ViewGroup继承自View,而且还新添了一个onInterceptTouchEvent()方法。

这三个方法的返回值都是boolean值,对于返回结果,如果return true,那么表示该方法消费了此次事件,如果return false,那么表示该方法并未处理完全,该事件仍然需要以某种方式传递下去继续等待处理。

一、dispatchTouchEvent

dispatchTouchEvent(MotionEventev) 这个方法用来分发TouchEvent,默认返回false。

先看下Activity中的注释和方法:

    /**
     * Called to process touch screen events.  You can override this to
     * intercept all touch screen events before they are dispatched to the
     * window.  Be sure to call this implementation for touch screen events
     * that should be handled normally.
     * 
     * @param ev The touch screen event.
     * 
     * @return boolean Return true if this event was consumed.
     */
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        if (ev.getAction() == MotionEvent.ACTION_DOWN)
        {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev))
        {
            return true;
        }
        return onTouchEvent(ev);
    }

注释说明:它会被调用处理触摸屏事件,可以重写覆盖此方法来拦截所有触摸屏事件在这些事件分发到窗口之前。通常应该处理触摸屏事件,一定要调用这个实现。当返回值为true时,表示这个事件已经被消费了。

源码简要说明下,onUserInteraction()是个空方法可忽略其影响。getWindow()返回当前Activity的顶层窗口Window对象。Window类的唯一子类是PhoneWindow,查看PhoneWindow的superDispatchTouchEvent()方法,里面又直接调用DecorView类的superDispatchTouchEvent()方法。DecorView是PhoneWindow的一个final的内部类并且继承FrameLayout的,也是Window界面的最顶层的View对象。DecorView类的superDispatchTouchEvent()方法又是调用了父类FrameLayout的dispatchTouchEvent()方法。而FrameLayout中并没有dispatchTouchEvent()方法,所以最后调用的还是ViewGroup的dispatchTouchEvent()方法。最后再通过ViewGroup的dispatchTouchEvent()方法将TouchEvent分发到其子View上。

ViewGroup和View中的dispatchTouchEvent()代码较多,具体的源码分析可参见:【转】Android笔记:触摸事件的分析与总结----Touch事件分发方法dispatchTouchEvent()源码分析

其他参考资料:http://blog.csdn.net/xiaanming/article/details/21696315。

二、onInterceptTouchEvent

onInterceptTouchEvent()是ViewGroup的一个方法,目的是在系统向该ViewGroup及其各个childView触发onTouchEvent()之前对相关事件进行一次拦截。

ViewGroup中onInterceptTouchEvent()方法及注释:

    /**
     * Implement this method to intercept all touch screen motion events. This
     * allows you to watch events as they are dispatched to your children, and
     * take ownership of the current gesture at any point.
     * 
     * <p>
     * Using this function takes some care, as it has a fairly complicated
     * interaction with {@link View#onTouchEvent(MotionEvent)
     * View.onTouchEvent(MotionEvent)}, and using it requires implementing that
     * method as well as this one in the correct way. Events will be received in
     * the following order:
     * 
     * <ol>
     * <li>You will receive the down event here.
     * <li>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.
     * <li>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().
     * <li>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
     * {@link MotionEvent#ACTION_CANCEL}, and all further events will be
     * delivered to your onTouchEvent() method and no longer appear here.
     * </ol>
     * 
     * @param ev
     *            The motion event being dispatched down the hierarchy.
     * @return Return true to steal motion events from the children and have
     *         them dispatched to this ViewGroup through onTouchEvent(). The
     *         current target will receive an ACTION_CANCEL event, and no
     *         further messages will be delivered here.
     */
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        return false;
    }

onInterceptTouchEvent()默认返回了false,注释的大意为重写该方法可以实现对触屏事件的拦截,使用该方法需要特别注意的是,该方法与View类的onTouchEvent(MotionEvent)或者View.onTouchEvent(MotionEvent)方法具有复杂的关联机制。结合onTouchEvent(),总结下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()处理。

三、onTouchEvent

onTouchEvent()的处理机制详见此文:

Android笔记:触摸事件的分析与总结----MotionEvent对象

四、TouchEvent处理范例

此处创建一个包含自定义LinearLayout(ViewGroup类)和自定义TextView(View类)的Activity来分析触摸屏幕时TouchEvent的处理机制。

效果图如下:

activity_main.xml代码如下:

<?xml version="1.0" encoding="utf-8"?> 
<com.example.d_touchevent.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:gravity="center" > 
       <com.example.d_touchevent.MyTextView 
            android:layout_width="100dp" 
            android:layout_height="100dp" 
            android:id="@+id/tv" 
            android:text="测试" 
            android:textSize="40sp" 
            android:textStyle="bold" 
            android:background="#F0F00F" 
            android:textColor="#0000FF"/> 
</com.example.d_touchevent.MyLinearLayout>

MainActivity.java代码如下:

package com.example.d_touchevent;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.MotionEvent;

/**
 * 参考资料:http://glblong.blog.51cto.com/3058613/1559320
 * @author zeng
 *
 */
public class MainActivity extends Activity
{
    private String TAG = "Activity ---  ";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        boolean b = super.onTouchEvent(event);
        
        
        int action = event.getAction();
        
        switch (action)
        {
        
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG , "ACTION_DOWN   --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_MOVE:
                
                Log.e(TAG, "ACTION_MOVE    --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_UP:
                
                Log.e(TAG, "ACTION_UP     --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_CANCEL:
                
                Log.e(TAG, "ACTION_CANCEL --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
        
        }
        
        
        return b;
    }
    
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        int action = ev.getAction();
        
        switch (action)
        {
        
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "ACTION_DOWN   --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_MOVE:
                
                Log.e(TAG, "ACTION_MOVE   --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_UP:
                
                Log.e(TAG, "ACTION_UP     --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_CANCEL:
                
                Log.e(TAG, "ACTION_CANCEL --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
        
        }
        return super.dispatchTouchEvent(ev);
    }
    
}

MyLinearLayout.java代码如下:

package com.example.d_touchevent;

import android.widget.LinearLayout;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

/**
 * 参考资料:http://glblong.blog.51cto.com/3058613/1559320
 * @author zeng
 *
 */
public class MyLinearLayout extends LinearLayout
{
    private final String TAG = "L布局    ---  ";
    
    public MyLinearLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        
        Log.e(TAG, TAG);
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        int action = ev.getAction();
        
        switch (action)
        {
        
            case MotionEvent.ACTION_DOWN:
                Log.e("", " ");
                Log.e("", " ");
                Log.e(TAG, "ACTION_DOWN   --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_MOVE:
                
                Log.e(TAG, "ACTION_MOVE   --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_UP:
                
                Log.e(TAG, "ACTION_UP     --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_CANCEL:
                
                Log.e(TAG, "ACTION_CANCEL --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
        
        }
        return super.dispatchTouchEvent(ev);
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        boolean b = false;
        
        int action = ev.getAction();
        switch (action)
        {
        
            case MotionEvent.ACTION_DOWN:
                
                Log.e(TAG, "ACTION_DOWN   --- " + TAG + "onInterceptTouchEvent 拦截 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_MOVE:
                
                Log.e(TAG, "ACTION_MOVE   --- " + TAG + "onInterceptTouchEvent 拦截 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_UP:
                
                Log.e(TAG, "ACTION_UP     --- " + TAG + "onInterceptTouchEvent 拦截 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_CANCEL:
                
                Log.e(TAG, "ACTION_CANCEL --- " + TAG + "onInterceptTouchEvent 拦截 --- " + b);
                
                break;
        
        }
        
        return b;
        
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent ev)
    {
        boolean b = true;
        
        int action = ev.getAction();
        switch (action)
        {
        
            case MotionEvent.ACTION_DOWN:
                
                Log.e(TAG, "ACTION_DOWN   --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_MOVE:
                
                Log.e(TAG, "ACTION_MOVE   --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_UP:
                
                Log.e(TAG, "ACTION_UP     --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_CANCEL:
                
                Log.e(TAG, "ACTION_CANCEL --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
        
        }
        
        return b;
    }
}

MyTextView.java代码如下:

package com.example.d_touchevent;

import android.widget.TextView;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

/**
 * 参考资料:http://glblong.blog.51cto.com/3058613/1559320
 * @author zeng
 *
 */
public class MyTextView extends TextView
{
    private final String TAG = "TextView ---  ";
    
    public MyTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        int action = ev.getAction();
        
        switch (action)
        {
        
            case MotionEvent.ACTION_DOWN:
                
                Log.e(TAG, "ACTION_DOWN   --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_MOVE:
                
                Log.e(TAG, "ACTION_MOVE   --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_UP:
                
                Log.e(TAG, "ACTION_UP     --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
            
            case MotionEvent.ACTION_CANCEL:
                
                Log.e(TAG, "ACTION_CANCEL --- " + TAG + "dispatchTouchEvent    分发 --- ");
                
                break;
        
        }
        return super.dispatchTouchEvent(ev);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent ev)
    {
        boolean b = false;
        
        int action = ev.getAction();
        switch (action)
        {
            case MotionEvent.ACTION_DOWN:
                Log.e(TAG, "ACTION_DOWN   --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_MOVE:
                
                Log.e(TAG, "ACTION_MOVE   --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_UP:
                
                Log.e(TAG, "ACTION_UP     --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
            
            case MotionEvent.ACTION_CANCEL:
                
                Log.e(TAG, "ACTION_CANCEL --- " + TAG + "onTouchEvent          处理 --- " + b);
                
                break;
        
        }
        
        return b;
        
    }
    

}

五、范例运行分析

注:a.以下Logcat中,若没有特别说明,dispatchTouchEvent()都按默认方法返回false。

b.为方便,L布局简写为L,TextView简写为T,Activity简写为A,下同。

1)点击范例中的【测试】按钮,运行日志如下:

结论:

当ACTION_DOWN事件产生时,首先触发了Activity的dispatchTouchEvent()方法;接着传递到ViewGroup上,触发L布局的dispatchTouchEvent()方法继续分发TouchEvent;L布局的onInterceptTouchEvent()方法为false,即不会拦截TouchEvent的传递,因而继续传递到ViewGroup里的View对象TextView中,此时仍然先是调用了TextView的dispatchTouchEvent()方法来处理TouchEvent的分发。从上到下依次传递:Activity -> L布局 -> TextView。

同理,当ACTION_UP事件产生时,首先也是Activity的dispatchTouchEvent()方法,接着再到L布局的dispatchTouchEvent()方法。

2)L.dispatchTouchEvent() = true ,运行日志如下:

   结论:

   此时,每个触摸事件产生时,都只执行到L布局的dispatchTouchEvent()方法,而不会继续再传递并触发其他方法。

3)A.dispatchTouchEvent() = false  &&  L.dispatchTouchEvent() = false  &&  T.dispatchTouchEvent() = true,运行日志如下:

结论:

由上可见,当TouchEvent由Activity传递到TextView时,执行到dispatchTouchEvent()后便结束了。也就是到TextView时,Android系统认为ACTION_DOWN和ACITON_UP都已经被消费了,而没有继续分发下去。

4)L.onInterceptTouchEvent = true   &&   L.onTouchEvent = true ,运行日志如下:

结论:

这种情况下,L布局处理了所有的TouchEvent。

5)L.onInterceptTouchEvent = true   &&   L.onTouchEvent = false , 运行日志如下:

   结论:

L布局只处理了ACTION_DOWN事件,而L布局最外层的ctivity处理了TouchEvent。

6)L.onInterceptTouchEvent=false  &&  L.onTouchEvent=true  &&  T.onTouchEvent=true , 运行日志如下:

结论:

TouchEvent完全由TextView处理。

7)L.onInterceptTouchEvent=false  &&  L.onTouchEvent=true  &&  T.onTouchEvent=false , 运行日志如下:

结论:

TextView只处理了ACTION_DOWN事件,LinearLayout处理了所有的TouchEvent。

六、分析总结

1.三个主要相关的方法的默认值

所有dispatchTouchEvent方法的默认值都是false。

ViewGroup里的onInterceptTouchEvent默认值是false这样才能把事件传给View里的onTouchEvent.

Activity和ViewGroup里的onTouchEvent默认值都是false。

View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件。

2.TouchEvent的处理流程

当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由  dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则表示该触摸事件已经被消费了,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“   消失”,而且接收不到下一次事件。

3.TouchEvent的处理流程图

自己制作了个TouchEvent处理的流程图,方便理清TouchEvent事件在各种UI对象以及对应方法中的处理机制。将流程图与上面的运行日志结合分析,发现对TouchEvent处理的机制清晰了很多。若有错误之处,欢迎指教。

时间: 2024-12-16 17:33:29

Android笔记:触摸事件的分析与总结----TouchEvent处理机制的相关文章

Android笔记:触摸事件的分析与总结----MotionEvent对象

一.MotionEvent对象 当用户触摸屏幕时,将创建一个MontionEvent对象.MotionEvent包含了关于发生触摸的位置和时间的信息,以及触摸事件的其他细节. 获取MontionEvent对象的方法有: 1.重载Activity中的onTouchEvent(MotionEvent event)方法; 2.View对象调用View.setOnTouchListener接口实现onTouch(View v, MotionEvent event)方法; 获得MontionEvent对象

Android笔记:触摸事件的分析与总结----多点触控

一.多点触控 当多点同时触摸屏幕时,系统将会产生如下的触摸事件: 1.ACTION_DOWN:触摸屏幕的第一个点.此时手势开始.该点的数据通常在MotionEvent事件队列索引位置0处. 2.ACTION_POINTER_DOWN:除了第一个点的其他触摸点数据.该点的数据的索引位置由getActionIndex()方法返回. 3.ACTION_MOVE:在手势过程中发生的一次变化. 4.ACTION_POINTER_UP:当不是第一个点的其他点UP后触发. 5.ACTION_UP:当手势中的最

Android ViewGroup 触摸事件传递机制

引言 上一篇博客我们学习了Android View 触摸事件传递机制,不了解的同学可以查看Android View 触摸事件传递机制.今天继续学习Android触摸事件传递机制,这篇博客将和大家一起探讨ViewGroup的触摸事件传递机制. 示例 示例代码如下: public class MainActivity extends ActionBarActivity { private String TAG = "MainActivity"; private MyViewGroup pa

Android View 触摸事件传递机制

PS:以现在的眼光看以前写的博客感觉写的很烂,或许或一段时间再看现在的博客会有同样的感觉.所以每时每刻都去学习,去发现和理解新的东西. 引言 由于之前写的一篇关于Android事件传递顺序的博客质量太差,可能是理解不到位的原因,故最近又花了许多时间再次去看Android源码,看完之后有了新的理解,所以打算重新整理这篇博客.理解Android触摸事件传递机制有助于日后的开发以及自定义一些手势效果等.注意:这篇博客是基于Android2.0源码来分析的,不管老版本还是新版本的Android,其内部触

一个demo让你彻底理解Android中触摸事件的分发

注:本文涉及的demo的地址:https://github.com/absfree/TouchDispatch 1. 触摸动作及事件序列 (1)触摸事件的动作 触摸动作一共有三种:ACTION_DOWN.ACTION_MOVE.ACTION_UP.当用户手指接触屏幕时,便产生一个动作为ACTION_DOWN的触摸事件,此时若用户的手指立即离开屏幕,会产生一个动作为ACTION_UP的触摸事件:若用户手指接触屏幕后继续滑动,当滑动距离超过了系统中预定义的距离常数,则产生一个动作为ACTION_MO

IOS学习笔记-触摸事件

一.事件传递的过程1.用户手指触摸屏幕,产生一个事件对象 2.系统会将这个事件对象添加到事件队列(先进先出)中 3.由UIApplication取出事件队列中的事件对象进行处理 4.UIApplication会先将事件对象传递给主要的UIWindow(当然,要先检测UIWindow是否能够接收和传递事件) 5.UIWindow会遍历所有的子控件,看看触摸点有没有落在某个子控件上面: 1> 如果触摸点没有落在子控件上,那么就由UIWindow直接处理这个事件,事件传递完毕 2> 如果触摸点落在子

Android 手势&amp;触摸事件

在刚开始学Android的时候,就觉得Google的文档不咋样,在研究手势时,更加的感觉Google的文档写得实在是太差了.很多常量,属性和方法,居然连个描述都没有.没有描述也就罢了,但是OnGestureListener里手势这么多,它也没有一个介绍说明,在没有进行不断才尝试之前,谁能搞懂onLongPress和onShowPress,onScroll和onFling的关系与差别吗?Google真的需要在文档方面做一次大手术了.不过好在经过鄙人不断反复的尝试.从个人的角度为这几个手势动作做出了

Android ViewGroup触摸事件拦截详解

前言 在自定义ViewGroup中,有时候需要实现触摸事件拦截,比如ListView下拉刷新就是典型的触摸事件拦截的例子.触摸事件拦截就是在触摸事件被parent view拦截,而不会分发给其child,即使触摸发生在该child身上.被拦截的事件会转到parent view的onTouchEvent方法中进行处理.但是这个交互过程还是挺复杂的,有多种情况,今天我们就来分析一下吧.这篇分析文章已经放了一段时间了,如果有任何问题请高人指出. 触摸事件的分发 简单来说触摸事件的分发会经过这么几个顺序

android屏幕触摸事件机制(转)

android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解.一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGro