这几天一直在研究onTouch的相关方法,今天我们就来看看onTouchEvent、dispatchTouchEvent、onIntercepTouchEvent这三个方法在控件之间的传递顺序

public boolean dispatchTouchEvent(MotionEvent ev)      //用于事件的分发

public boolean onInterceptTouchEvent(MotionEvent ev)    //  用于事件的拦截

public boolean onTouchEvent(MotionEvent ev)     //处理事件

先看如下代码

1)xml文件

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.mygestrue.MainActivity" > <com.example.mygestrue.MyLinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <com.example.mygestrue.MyLinearLayoutT
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <com.example.mygestrue.MyTextView
android:id="@+id/tv1"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#0000ff"
android:text="@string/hello_world" /> <com.example.mygestrue.MyTextViewT
android:layout_marginTop="50dp"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#ff0000"
android:text="@string/hello_world" />
</com.example.mygestrue.MyLinearLayoutT>
</com.example.mygestrue.MyLinearLayout> </RelativeLayout>

2)上面用到的几个自定义的类

MyLinearLayout

package com.example.mygestrue;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout; public class MyLinearLayout extends LinearLayout { public MyLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
} public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
} public MyLinearLayout(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("123", "myll1_ontouchevent");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
Log.e("123", "myll1_dispatchTouchevent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
Log.e("123", "myll1_oninterceptouchevent");
return super.onInterceptTouchEvent(ev);
}
}

MyLinearLayoutT

package com.example.mygestrue;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout; public class MyLinearLayoutT extends LinearLayout { public MyLinearLayoutT(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
} public MyLinearLayoutT(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
} public MyLinearLayoutT(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("123", "myll2_ontouchevent");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
Log.e("123", "myll2_dispatchTouchevent");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
Log.e("123", "myll2_oninterceptouchevent");
return super.onInterceptTouchEvent(ev);
}
}

MyTextView

package com.example.mygestrue;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView; public class MyTextView extends TextView { 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
} public MyTextView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("123", "mytv1_ontouchevent");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("123", "mytv1_dispatchtouchevent");
return super.dispatchTouchEvent(event);
}
}

MyTextViewT

package com.example.mygestrue;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView; public class MyTextViewT extends TextView { public MyTextViewT(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
} public MyTextViewT(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
} public MyTextViewT(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("123", "mytv2_ontouchevent");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("123", "mytv2_dispatchtouchevent");
return super.dispatchTouchEvent(event);
}
}

MainActivity

package com.example.mygestrue;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
public class MainActivity extends ActionBarActivity {
; @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
Log.e("123", "main_dispatchtouchevent");
return super.dispatchTouchEvent(ev);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present. return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml. return super.onOptionsItemSelected(item);
} @Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("123", "main_ontouchevent");
// return super.onTouchEvent(event);
return super.onTouchEvent(event);
}; }

1.当我们点击屏幕空白处的时候,打印的log

- ::16.879: E/(): main_dispatchtouchevent
- ::16.879: E/(): myll1_dispatchTouchevent
- ::16.879: E/(): myll1_oninterceptouchevent
- ::16.879: E/(): myll2_dispatchTouchevent
- ::16.879: E/(): myll2_oninterceptouchevent
- ::16.880: E/(): myll2_ontouchevent
- ::16.881: E/(): myll1_ontouchevent
- ::16.882: E/(): main_ontouchevent - ::17.748: E/(): main_dispatchtouchevent
- ::17.748: E/(): myll1_dispatchTouchevent
- ::17.748: E/(): myll1_oninterceptouchevent
- ::17.749: E/(): myll2_dispatchTouchevent
- ::17.749: E/(): myll2_oninterceptouchevent
- ::17.749: E/(): myll2_ontouchevent
- ::17.749: E/(): myll1_ontouchevent
- ::17.751: E/(): main_ontouchevent

得出的结论是

首先是Activity_dispatchTouchEvent->xml最外层容器_dispatchTouchEvent->xml最外层容器_onIntercepTouchEvent->下一层_dispatchTouchEvent->下一层_onIntercepTouchEvent->最末层_onTouchEvent->上一层_onTouchEvent->最外层_onTouchEvent->Activity_onTouchEvent

现在我们更改一下这些touch事件的返回值,如下

activity:

 dispatchTouchEvent:true
onTouchEvent :true linear1: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true linear2: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true

打印的log如下

- ::32.237: E/(): main_dispatchtouchevent
- ::32.267: E/(): main_dispatchtouchevent
- ::32.283: E/(): main_dispatchtouchevent
- ::32.300: E/(): main_dispatchtouchevent
- ::32.317: E/(): main_dispatchtouchevent
- ::32.335: E/(): main_dispatchtouchevent
- ::32.341: E/(): main_dispatchtouchevent
- ::32.914: E/(): main_dispatchtouchevent
- ::32.933: E/(): main_dispatchtouchevent
- ::32.951: E/(): main_dispatchtouchevent
- ::32.968: E/(): main_dispatchtouchevent
- ::32.985: E/(): main_dispatchtouchevent
- ::33.002: E/(): main_dispatchtouchevent
- ::33.006: E/(): main_dispatchtouchevent

只有main_dispatchtouchevent执行了

activity:

 dispatchTouchEvent:false
onTouchEvent :true linear1: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true linear2: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true

打印log

- ::45.660: E/(): main_dispatchtouchevent
- ::45.688: E/(): main_dispatchtouchevent
- ::45.706: E/(): main_dispatchtouchevent
- ::45.723: E/(): main_dispatchtouchevent
- ::45.740: E/(): main_dispatchtouchevent
- ::45.748: E/(): main_dispatchtouchevent

还是仅仅执行了main_dispatchtouchevent

activity:

 dispatchTouchEvent:false
onTouchEvent :false linear1: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true linear2: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true

打印log

- ::26.545: E/(): main_dispatchtouchevent
- ::26.563: E/(): main_dispatchtouchevent
- ::26.580: E/(): main_dispatchtouchevent
- ::26.598: E/(): main_dispatchtouchevent
- ::26.615: E/(): main_dispatchtouchevent
- ::26.632: E/(): main_dispatchtouchevent
- ::26.649: E/(): main_dispatchtouchevent
- ::26.650: E/(): main_dispatchtouchevent

结果还是一样:执行的是main_dispatchtouchevent

activity:

 dispatchTouchEvent:false
onTouchEvent :false linear1: dispatchTouchEvent:false
onTouchEvent :true
onInterceptTouchEvent:true linear2: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true

打印log

- ::04.697: E/(): main_dispatchtouchevent
- ::04.722: E/(): main_dispatchtouchevent
- ::04.739: E/(): main_dispatchtouchevent
- ::04.757: E/(): main_dispatchtouchevent
- ::04.774: E/(): main_dispatchtouchevent
- ::04.792: E/(): main_dispatchtouchevent
- ::04.796: E/(): main_dispatchtouchevent

结果仍然没有改变 main_dispatchtouchevent被执行

activity:

 dispatchTouchEvent:false
onTouchEvent :false linear1: dispatchTouchEvent:false
onTouchEvent :true
onInterceptTouchEvent:false linear2: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true
- ::23.294: E/(): main_dispatchtouchevent
- ::23.318: E/(): main_dispatchtouchevent
- ::23.336: E/(): main_dispatchtouchevent
- ::23.353: E/(): main_dispatchtouchevent
- ::23.370: E/(): main_dispatchtouchevent
- ::23.387: E/(): main_dispatchtouchevent
- ::23.390: E/(): main_dispatchtouchevent

好吧,忽然感觉,这个时候,仅仅让activity中的ontouch事件纯粹返回true或者false是没有意义的,这样事件好像根本就没办法往下传了

activity:

 dispatchTouchEvent:super.dispatchTouchEvent(ev)
onTouchEvent :false linear1: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true linear2: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true
- ::18.871: E/(): main_dispatchtouchevent
- ::18.872: E/(): myll1_dispatchTouchevent
- ::18.896: E/(): main_dispatchtouchevent
- ::18.897: E/(): myll1_dispatchTouchevent
- ::18.912: E/(): main_dispatchtouchevent
- ::18.913: E/(): myll1_dispatchTouchevent
- ::18.929: E/(): main_dispatchtouchevent
- ::18.929: E/(): myll1_dispatchTouchevent
- ::18.947: E/(): main_dispatchtouchevent
- ::18.948: E/(): myll1_dispatchTouchevent
- ::18.964: E/(): main_dispatchtouchevent
- ::18.964: E/(): myll1_dispatchTouchevent
- ::18.978: E/(): main_dispatchtouchevent
- ::18.978: E/(): myll1_dispatchTouchevent
- ::18.979: E/(): main_dispatchtouchevent
- ::18.979: E/(): myll1_dispatchTouchevent

我们看到,这时候,ll1接收到了main_dispatchtouchevent传过来的事件,但是,它并没有继续往下传

activity:

 dispatchTouchEvent:super.dispatchTouchEvent(ev)
onTouchEvent :false linear1: dispatchTouchEvent:false
onTouchEvent :true
onInterceptTouchEvent:true linear2: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:true tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true
- ::58.037: E/(): main_dispatchtouchevent
- ::58.037: E/(): myll1_dispatchTouchevent
- ::58.039: E/(): main_ontouchevent
- ::58.056: E/(): main_dispatchtouchevent
- ::58.056: E/(): main_ontouchevent
- ::58.073: E/(): main_dispatchtouchevent
- ::58.073: E/(): main_ontouchevent
- ::58.090: E/(): main_dispatchtouchevent
- ::58.090: E/(): main_ontouchevent
- ::58.108: E/(): main_dispatchtouchevent
- ::58.108: E/(): main_ontouchevent
- ::58.122: E/(): main_dispatchtouchevent
- ::58.122: E/(): main_ontouchevent
- ::58.122: E/(): main_dispatchtouchevent
- ::58.123: E/(): main_ontouchevent

我们看到ll1接收到了main_dispatchtouchevent的事件,但是,这时候,ll1的dispatchtouchevent的返回值为false,就是说,这个事件不往下分发,而ll1的interceptouchevent返回值又为true,也就是说,事件拦截,所以它的ontouch就不执行了,这样,就直接执行到了main_touchevent了

activity:

 dispatchTouchEvent:super.dispatchTouchEvent(ev)
onTouchEvent :false linear1: dispatchTouchEvent:true
onTouchEvent :true
onInterceptTouchEvent:false linear2: dispatchTouchEvent:false
onTouchEvent :true
onInterceptTouchEvent:false tv1: dispatchTouchEvent:true
onTouchEvent :true tv2: dispatchTouchEvent:true
onTouchEvent :true

ontouch、dispatchtouchevent、interceptouchevent-相关事件的更多相关文章

  1. Redis集群~StackExchange.redis连接Sentinel服务器并订阅相关事件(原创)

    回到目录 对于redis-sentinel我在之前的文章中已经说过,它是一个仲裁者,当主master挂了后,它将在所有slave服务器中进行选举,选举的原则当然可以看它的官方文章,这与我们使用者没有什 ...

  2. 移动端前端常见的触摸相关事件touch、tap、swipe等整理

    前端的很多事件在PC端和浏览器端可公用,但有些事件却只在移动端产生,如触摸相关的事件 本文整理了移动端常见的一些事件,包括原生支持的click.touch.tap.swipe事件,也有定义型的gest ...

  3. android onclick onLongClick ontouch dispatchTouchEvent onInterceptTouchEvent

    android onclick onLongClick ontouch dispatchTouchEvent onInterceptTouchEvent 按ACTION_DOWN -> onLo ...

  4. 与众不同 windows phone (24) - Input(输入)之软键盘类型, XNA 方式启动软键盘, UIElement 的 Touch 相关事件, 触摸涂鸦

    原文:与众不同 windows phone (24) - Input(输入)之软键盘类型, XNA 方式启动软键盘, UIElement 的 Touch 相关事件, 触摸涂鸦 [索引页][源码下载] ...

  5. 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, VerticalAlignment

    [源码下载] 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, Vertical ...

  6. 背水一战 Windows 10 (68) - 控件(控件基类): UIElement - Pointer 相关事件, Tap 相关事件, Key 相关事件, Focus 相关事件

    [源码下载] 背水一战 Windows 10 (68) - 控件(控件基类): UIElement - Pointer 相关事件, Tap 相关事件, Key 相关事件, Focus 相关事件 作者: ...

  7. Android的相关事件

    Android的相关事件 1.Toast信息提醒 import android.support.v7.app.AppCompatActivity; import android.os.Bundle; ...

  8. video播放视频以及相关事件

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  9. video元素和audio元素相关事件

    前言 在利用video元素或audio元素读取或播放媒体数据时,会触发一系列事件,如果用js脚本来捕抓这些事件,就可以对着这些事件进行处理了. 捕抓的方式有两种: 第一种是监听的方式.使用vedio或 ...

  10. [jQuery编程挑战]003 克隆一个页面元素及其相关事件

    挑战: a) 绑定一个点击方法到这个div,点击后此元素会淡出消失 b) 同时克隆一个新的div元素到页面,元素内容是前面div文字内容反向书写(即,sgatbg olleh),同样也具有上面的点击事 ...

随机推荐

  1. HDU 5371 Hotaru's problem Manacher+尺取法

    题意:给你一个序列,求最长的两段回文子串,要求他们共用中间的一半. 思路:利用Manacher求出p[i]表示的当前位置的最长回文串长度,然后把每一个长度大于等于2的回文串的左区间和右区间分别放到两个 ...

  2. modelForm所遇问题

    1. 通过modelForm创建表单所遇问题 id 在modelForm中无法创建使用 因为它是django的设置,自增的字段,而不是模型中所设置的字段. 当关联外键时,创建多选的下拉框时,需要注意此 ...

  3. linux下,yum 安装mysql

    顺手记录一下安装mysqlclient 先安装mysql-devel yum install mysql-devel 再安装mysqlclient pip3 install mysqlclient 开 ...

  4. 【VC++学习笔记三】控件自绘

    MFC应用程序中,大部分的控件类型都已经被定制好了,即便是修改,也只是小范围内的修改,而很多情况下,我们又需要对界面进行特殊定制,这时,最好的办法就是用CWnd类进行派生,自己生成新的窗体,在WM_P ...

  5. 03013_JDBC工具类

    1.“获得数据库连接”操作,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils.提供获取连接对象的方法,从而达到代码的重复利用. 2.该工具类提供方法:public static C ...

  6. android反编译odex文件

    关于android的反编译工具,相信大家并不陌生 如APK-TOOL,dex2jar APK-TOOL 用于反编译出布局文件 下载地址http://code.google.com/p/android- ...

  7. 压缩感知——SP(subspace pursuit)重构算法前言翻译

    压缩感知是一种採样方法,它和变换编码类似,后者被广泛用于涉及到大规模数据採样的现代通信系统中.变换编码将高维空间中的输入信号.转换成很低的低维空间中的信号.变换编码器的样例有著名的小波变换和普遍存在的 ...

  8. [转]C语言预处理命令详解

    转载:https://www.cnblogs.com/clover-toeic/p/3851102.html 一  前言 预处理(或称预编译)是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的 ...

  9. JavaFX 一 出生新手村(阅读小规则)

    我就不讲IDE怎么装的,网上有的是,我仅仅是说说我学习过程中遇到的,该注意的东西 1.JavaFX刚開始出是基于脚本script开发的语言,所以网上会有流传比較多关于script的JavaFX,对于被 ...

  10. 数据库优化技巧之in和not in

    在编写SQL语句时,假设要实现一张表有而另外一张表没有的数据时. 通常第一直觉的写法是: select * from table1 where table1.id not in(select id f ...