这几天一直在研究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. HtmlHelper的扩展分页方法

    一.新建一个空MVC项目,命名为MVCAppPager 二.新建一个文件夹PageHelper,在文件夹下新建接口IPageList以及实现类PageList IPageList接口: public ...

  2. Html+CSS基础之CSS样式

    认识CSS样式 CSS全称为“层叠样式表 (Cascading Style Sheets)”,它主要是用于定义HTML内容在浏览器内的显示样式,如文字大小.颜色.字体加粗等. 如下列代码: p{ fo ...

  3. 113.dynamic_cast 虚函数 通过子类初始化的父类转化为子类类型

    #include <iostream> using namespace std; //子类同名函数覆盖父类 //父类指针存储子类地址,在有虚函数情况会调用子类方法,否则会调用父类方法 cl ...

  4. POJ 1167 The Buses 暴搜+剪枝

    思路: 先把能选的路线都预处理出来 按照能停的车的多少排个序 (剪枝1) 搜搜搜 如果当前剩的车÷当前能停车的多少+deep>=ans剪掉 (剪枝2) //By SiriusRen #inclu ...

  5. leetcode 10 Regular Expression Matching(简单正则表达式匹配)

    最近代码写的少了,而leetcode一直想做一个python,c/c++解题报告的专题,c/c++一直是我非常喜欢的,c语言编程练习的重要性体现在linux内核编程以及一些大公司算法上机的要求,pyt ...

  6. sql中 where语句的用法

    //查询user_id 10到20 之间  30到40之间 //查询user_id 不在10到20之间的

  7. MySQL Field排序法

    检索 id = 2 or id = 5 or id = 9 or id = 56 or id = 38.然后按照 2 , 5, 9, 56, 38 这个顺序排列,这是题目要求   以下为解决方案: 1 ...

  8. 解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)

    问题 如下: 2017-07-16 08:50:57.436  INFO 13524 --- [           main] c.p.p.web.PointshopWebApplication   ...

  9. Java技术——Java泛型详解(转)

    ); for (int i = 0; i < list.size(); i++) { String name = (String) list.get(i); //取出Integer时,运行时出现 ...

  10. 【v2.x OGE教程 12】 关卡编辑器帮助文档

    ] 关卡编辑器帮助文档 一.简单介绍 关卡编辑器用于游戏关卡界面元素的可视化编辑,包含元素的位置.尺寸以及其他自己定义属性.通过解析生成的数据文件就可以获取关卡信息,并能随时调整.以降低开发工作量,提 ...