这几天一直在研究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. Design Pattern - Service Locator Pattern--转载

    原文地址:http://www.tutorialspoint.com/design_pattern/service_locator_pattern.htm The service locator de ...

  2. HTTP 与 HTTPS

    https就是http和TCP之间有一层SSL层,这一层的实际作用是防止钓鱼和加密. 防止钓鱼通过网站的证书,网站必须有CA证书,证书类似于一个解密的签名. 另外是加密,加密需要一个密钥交换算法,双方 ...

  3. Linux常用视频播放器

    1.SMplayer是一款跨平台的视频播放工具,可以支持大部分的视频和音频文件.它支持音频轨道切换.允许调节亮度.对比度.色调.饱和度.伽玛值,按照倍速.4倍速等多种速度回放.还可以进行音频和字幕延迟 ...

  4. CodeBlocks 配色方案

    搜索<colour_sets>,在</ACTIVE_LANG>下加入: 有几种经典方案,包括vim,desert,sublime,ulipad,oblivion,darkgra ...

  5. 紫书 例题 9-12 UVa 12186 (树形dp)

    这道题还是比较简单的,对于当前节点,算出每个儿子需要的人数 然后再算出当前节点需要多少个人数,然后排个序加上去就好了. #include<cstdio> #include<vecto ...

  6. Swift学习笔记(6)--字典

    1.定义 //1.基本定义 [key 1: value 1, key 2: value 2, key 3: value 3] var dict = ["name":"Xi ...

  7. windows10系统下设置mtu值的方法

     windows10系统下设置mtu值的方法 http://www.xitongcheng.com/jiaocheng/win10_article_34701.html 以下为服务器上使用  ip ...

  8. JSP_Learn

    // 解决中文乱码的问题String name = new String((request.getParameter("name")).getBytes("ISO-885 ...

  9. [log4j]Slf4j的包冲突

    Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFa ...

  10. mac: brew的删除

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" ...