Android中dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent事件分析

因为触摸事件一定会触发的ACTION是DOWN,这个也是最先触发的,所以标题中的三个方法研究的也就是这个DOWN事件的传递情况。

下面直接贴出测试代码,边看边讲:

一个Activity,Activity中只有dispatchTouchEvent和onTouchEvent方法。

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return super.onTouchEvent(event);
    }
}

三个自定义的控件,前两个是ViewGroup类型,后一个是view类型。

ViewGroup有dispatchTouchEvent,onInterceptTouchEvent和onTouchEvent方法。

public class MyLinearLayout1 extends LinearLayout
{
    public MyLinearLayout1(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout1(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout1(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onInterceptTouchEvent");
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return super.onTouchEvent(event);
    }
}
public class MyLinearLayout2 extends LinearLayout
{
    public MyLinearLayout2(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout2(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public MyLinearLayout2(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onInterceptTouchEvent");
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return true;
    }
}
public class MyTextView extends TextView
{
    public MyTextView(Context context)
    {
        super(context);
        // TODO Auto-generated constructor stub
    }

    public MyTextView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public MyTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " dispatchTouchEvent");
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        // TODO Auto-generated method stub
        System.out.println(getClass().getSimpleName() + " onTouchEvent");
        return super.onTouchEvent(event);
    }
}
<com.testtouchevent.MyLinearLayout1 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <com.testtouchevent.MyLinearLayout2
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/darker_gray"
        android:orientation="vertical"
        android:padding="20dp" >

        <com.testtouchevent.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            android:gravity="center"
            android:padding="20dp"
            android:text="me is textview" />
    </com.testtouchevent.MyLinearLayout2>

</com.testtouchevent.MyLinearLayout1>

以上代码中各控件的相关方法执行顺序是这样的:

MainActivity                MyLinearLayout1                                             MyLinearLayout2                                            MyTextView

dispatchTouchEvent->dispatchTouchEvent->onInterceptTouchEvent->dispatchTouchEvent->onInterceptTouchEvent->dispatchTouchEvent

onTouchEvent<-        onTouchEvent<-                                                     onTouchEvent<-                                    onTouchEvent

dispatchTouchEvent:决定了事件是否继续分发下去和是否响应事件,false:继续分发,true:不继续分发,此次事件到此结束,也不会有任何控件执行onTouchEvent方法。

onInterceptTouchEvent:决定了是否拦截该事件,false:不拦截,true:拦截,此时当前控件执行onTouchEvent方法。

onTouchEvent:决定了是否消费该事件,false:不消费,true:消费。

时间: 2024-11-10 19:54:11

Android中dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent事件分析的相关文章

Android中dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的理解

[转]http://blog.csdn.net/guitk/article/details/7057155 onInterceptTouchEvent用于改变事件的传递方向.决定传递方向的是返回值,返回为false时事件会传递给子控件,返回值为true时事件会传递给当前控件的onTouchEvent(),这就是所谓的Intercept(拦截). [tisa ps:正确的使用方法是,在此方法内仅判断事件是否需要拦截,然后返回.即便需要拦截也应该直接返回true,然后由onTouchEvent方法进

dispatchTouchEvent(),onInterceptTouchEvent()和onTouchEvent()的事件分发

在布局文件里,假设有3层 , 一层是button, textview等常见组件, 二层是嵌套的RelativeLayout, 三层是LinearLayout, 而一个触摸屏幕的事件无非就是ACTION_DOWN, ACTION_MOVE, ACTION_UP.  而手指从按下到松开离开屏幕, 其实事件分发的传递已经经过了这三层. 这里说下它的处理过程, 也算是巩固记忆了. 首先, dispatchTouchEvent(),onInterceptTouchEvent()和onTouchEvent(

Android中按钮的点击事件的四种写法

如题,在Android中按钮的点击事件有四种写法,如下图. 界面为四个Button+一个TextView+一个ImageView activity_main布局文件如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="

Android 中View的绘制机制源代码分析 三

到眼下为止,measure过程已经解说完了,今天開始我们就来学习layout过程.只是在学习layout过程之前.大家有没有发现我换了编辑器,哈哈.最终下定决心从Html编辑器切换为markdown编辑器.这里之所以使用"下定决心"这个词.是由于毕竟Html编辑器使用好几年了.非常多习惯都已经养成了,要改变多年的习惯确实不易.相信这也是还有非常多人坚持使用Html编辑器的原因. 这也反应了一个现象.当人对某一事物非常熟悉时,一旦出现了新的事物想代替老的事物时,人们都有一种抵触的情绪,做

Android中Input型输入设备驱动原理分析(一)

转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反正这个是没变的,在android的底层开发中对于Linux的基本驱动程序设计还是没变的,当然Android底层机制也增加几个属于android自己的机制.典型的IPC Android中的input设备驱动主要包括:游戏杆(joystick).鼠标(mouse)和事件设备(Event). 1.Inpu

Android中对Log日志文件的分析

一,Bug出现了, 需要“干掉”它 bug一听挺吓人的,但是只要你懂了,android里的bug是很好解决的,因为android里提供了LOG机制,具体的底层代码,以后在来分析,只要你会看bug, android里应用开发也就很简单了. 那我们先来看看android里的ANR,怎么出现ANR呢,很简单. # adb shell # cd data/app #  monkey   -p  com.xxx.xxx   -v   3000      (com.xxx.xxx是你应用程序的包名,如果想知

Android 中 View 炸裂特效的实现分析 &lt;IT蓝豹&gt;

前几天微博上被一个很优秀的 Android 开源组件刷屏了 - ExplosionField,效果非常酷炫,有点类似 MIUI 卸载 APP 时的动画,先来感受一下. ExplosionField 不但效果很拉风,代码写得也相当好,让人忍不住要拿来好好读一下. 创建 ExplosionField ExplosionField 继承自 View,在 onDraw 方法中绘制动画特效,并且它提供了一个 attach2Window 方法,可以把 ExplosionField 最为一个子 View 添加

android中多次点击事件的实现

1.在android系统中,设置里面->关于手机->安卓版本(即android version),三击后会出现android该个版本的版本号,以及一些动图,算是一个彩蛋吧! 2.导入setting源代码,ctrl+h搜索文件(关键字Android Version),搜索到了之后打开xml文件 3.是一个strings.xml文件,再次找到关键字firmware_version,再搜索.找到src下的源代码文件 4.又找到一个关键字KEY_FIRMWARE_VERSION,翻一翻找到关于多次点击

Android中InCallUI显示太慢问题分析

一.问题现象 当手机有来电时,先听到铃声,过了比较长的一段时间(3-4s)屏幕才点亮并显示来电界面. Platform:MT6581 Android版本:4.4KK BuildType:userdebug 系统软件版本:SWC1E+UP 系统RAM:512M 二.Android4.4来电及IncallUI显示的流程 三.问题分析 四.解决方案 五.应用解决方案之后的对比分析 六.结论 完整分析流程和详细内容请直接下载PDF文档: InCallUI_issue_analysis_report