android onInterceptTouchEvent onTouchEvent

参考文档:

http://blog.csdn.net/liutao5757124/article/details/6097125

首先,看Android的官方文档正解

onInterceptTouchEvent()与onTouchEvent()的机制:

  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()处理

这是官方文档的说法,要是自己没亲自去写个程序观察哈,基本上没法理解,所以上程序先,然后分析:

布局文件main.xml

Java代码  

  1. <span style="font-size: small;"><?xml version="1.0" encoding="utf-8"?>
  2. <com.hao.LayoutView1 xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical" android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <com.hao.LayoutView2
  6. android:orientation="vertical" android:layout_width="fill_parent"
  7. android:layout_height="fill_parent" android:gravity="center">
  8. <com.hao.MyTextView
  9. android:layout_width="wrap_content" android:layout_height="wrap_content"
  10. android:id="@+id/tv" android:text="AB" android:textSize="40sp"
  11. android:textStyle="bold" android:background="#FFFFFF"
  12. android:textColor="#0000FF" />
  13. </com.hao.LayoutView2>
  14. </com.hao.LayoutView1>
  15. </span>

第一层自定义布局LayoutView1.java

Java代码  

  1. <span style="font-size: small;">package com.hao;
  2. import android.content.Context;
  3. import android.util.AttributeSet;
  4. import android.util.Log;
  5. import android.view.MotionEvent;
  6. import android.widget.LinearLayout;
  7. public class LayoutView1 extends LinearLayout {
  8. private final String TAG = "LayoutView1";
  9. public LayoutView1(Context context, AttributeSet attrs) {
  10. super(context, attrs);
  11. Log.e(TAG,TAG);
  12. }
  13. @Override
  14. public boolean onInterceptTouchEvent(MotionEvent ev) {
  15. int action = ev.getAction();
  16. switch(action){
  17. case MotionEvent.ACTION_DOWN:
  18. Log.e(TAG,"onInterceptTouchEvent action:ACTION_DOWN");
  19. //              return true; 在这就拦截了,后面的就不会得到事件
  20. break;
  21. case MotionEvent.ACTION_MOVE:
  22. Log.e(TAG,"onInterceptTouchEvent action:ACTION_MOVE");
  23. break;
  24. case MotionEvent.ACTION_UP:
  25. Log.e(TAG,"onInterceptTouchEvent action:ACTION_UP");
  26. break;
  27. case MotionEvent.ACTION_CANCEL:
  28. Log.e(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");
  29. break;
  30. }
  31. return false;
  32. }
  33. @Override
  34. public boolean onTouchEvent(MotionEvent ev) {
  35. int action = ev.getAction();
  36. switch(action){
  37. case MotionEvent.ACTION_DOWN:
  38. Log.e(TAG,"onTouchEvent action:ACTION_DOWN");
  39. break;
  40. case MotionEvent.ACTION_MOVE:
  41. Log.e(TAG,"onTouchEvent action:ACTION_MOVE");
  42. break;
  43. case MotionEvent.ACTION_UP:
  44. Log.e(TAG,"onTouchEvent action:ACTION_UP");
  45. break;
  46. case MotionEvent.ACTION_CANCEL:
  47. Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");
  48. break;
  49. }
  50. return true;
  51. //         return false;
  52. }
  53. @Override
  54. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  55. // TODO Auto-generated method stub
  56. super.onLayout(changed, l, t, r, b);
  57. }
  58. @Override
  59. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  60. // TODO Auto-generated method stub
  61. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  62. }
  63. }</span>

第二层布局LayoutView2.java

Java代码  

  1. <span style="font-size: small;">package com.hao;
  2. import android.content.Context;
  3. import android.util.AttributeSet;
  4. import android.util.Log;
  5. import android.view.MotionEvent;
  6. import android.widget.LinearLayout;
  7. public class LayoutView2 extends LinearLayout {
  8. private final String TAG = "LayoutView2";
  9. public LayoutView2(Context context, AttributeSet attrs) {
  10. super(context, attrs);
  11. Log.e(TAG,TAG);
  12. }
  13. @Override
  14. public boolean onInterceptTouchEvent(MotionEvent ev) {
  15. int action = ev.getAction();
  16. switch(action){
  17. case MotionEvent.ACTION_DOWN:
  18. Log.e(TAG,"onInterceptTouchEvent action:ACTION_DOWN");
  19. //           return true;
  20. break;
  21. case MotionEvent.ACTION_MOVE:
  22. Log.e(TAG,"onInterceptTouchEvent action:ACTION_MOVE");
  23. break;
  24. case MotionEvent.ACTION_UP:
  25. Log.e(TAG,"onInterceptTouchEvent action:ACTION_UP");
  26. break;
  27. case MotionEvent.ACTION_CANCEL:
  28. Log.e(TAG,"onInterceptTouchEvent action:ACTION_CANCEL");
  29. break;
  30. }
  31. return false;
  32. }
  33. @Override
  34. public boolean onTouchEvent(MotionEvent ev) {
  35. int action = ev.getAction();
  36. switch(action){
  37. case MotionEvent.ACTION_DOWN:
  38. Log.e(TAG,"onTouchEvent action:ACTION_DOWN");
  39. break;
  40. case MotionEvent.ACTION_MOVE:
  41. Log.e(TAG,"onTouchEvent action:ACTION_MOVE");
  42. break;
  43. case MotionEvent.ACTION_UP:
  44. Log.e(TAG,"onTouchEvent action:ACTION_UP");
  45. break;
  46. case MotionEvent.ACTION_CANCEL:
  47. Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");
  48. break;
  49. }
  50. //       return true;
  51. return false;
  52. }
  53. }
  54. </span>

自定义MyTextView.java

Java代码  

  1. <span style="font-size: small;">package com.hao;
  2. import android.content.Context;
  3. import android.util.AttributeSet;
  4. import android.util.Log;
  5. import android.view.MotionEvent;
  6. import android.view.View;
  7. import android.widget.TextView;
  8. public class MyTextView extends TextView {
  9. private final String TAG = "MyTextView";
  10. public MyTextView(Context context, AttributeSet attrs) {
  11. super(context, attrs);
  12. Log.e(TAG,TAG);
  13. }
  14. @Override
  15. public boolean onTouchEvent(MotionEvent ev) {
  16. int action = ev.getAction();
  17. switch(action){
  18. case MotionEvent.ACTION_DOWN:
  19. Log.e(TAG,"onTouchEvent action:ACTION_DOWN");
  20. break;
  21. case MotionEvent.ACTION_MOVE:
  22. Log.e(TAG,"onTouchEvent action:ACTION_MOVE");
  23. break;
  24. case MotionEvent.ACTION_UP:
  25. Log.e(TAG,"onTouchEvent action:ACTION_UP");
  26. break;
  27. case MotionEvent.ACTION_CANCEL:
  28. Log.e(TAG,"onTouchEvent action:ACTION_CANCEL");
  29. break;
  30. }
  31. return false;
  32. //       return true;
  33. }
  34. public void onClick(View v) {
  35. Log.e(TAG, "onClick");
  36. }
  37. public boolean onLongClick(View v) {
  38. Log.e(TAG, "onLongClick");
  39. return false;
  40. }
  41. }
  42. </span>

其实代码很简单,就是自定义了View,在View里面都重写了interceptTouchEvnet (),和onTouchEvent(),然后测试其返回值,对监听的影响,关键是自己动手,逐个测试,并预测结果,等你能预测结果的时候,也就懂了,需要修改的地方就是interceptTouchEvnet 和onTouchEvent的返回值,他们决定了事件监听的流程,下面我画了一张图,如有不足之处欢迎指正,谢谢!

下面是我的正解:

基本的规则是:

*1.down事件首先会传递到onInterceptTouchEvent()方法

*

* 2.如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false(不拦截),

* 那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。

*

* 3.如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true(拦截,那么后面的move,up事件不需要在看因为已经拦截了, 我们直接拿去处理onTouchEvent()就可以了),那么后续的move, up等事件将不再传递给onInterceptTouchEvent(), 而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。
下面例子演示:

* 1:LayoutView1(31375): onInterceptTouchEvent action:ACTION_DOWN

* 2:LayoutView2(31375): onInterceptTouchEvent action:ACTION_DOWN

* 3:LayoutView2(31375): onTouchEvent action:ACTION_DOWN

* 4:LayoutView1(31375): onInterceptTouchEvent action:ACTION_MOVE

* 5:LayoutView2(31375): onTouchEvent action:ACTION_MOVE

* 6:LayoutView1(31375): onInterceptTouchEvent action:ACTION_MOVE

* 7:LayoutView2(31375): onTouchEvent action:ACTION_MOVE

* 8:LayoutView1(31375): onInterceptTouchEvent action:ACTION_UP

* 9:LayoutView2(31375): onTouchEvent action:ACTION_UP

* 该设置为:

* onInterceptTouchEvent:LayoutView1为false,LayoutView2为true

* onTouchEvent:LayoutView2为true

* 故而事件在LayoutView2(onInterceptTouchEvent:返回true)时被拦截并处理,根据上面说法就是LayoutView2后续的MOVE,UP操作都不在经过onInterceptTouchEvent,直接

* 交给onTouchEvent处理,结果也的确如此。(见:LayoutView2的3,5,7,9,第一次是onInterceptTouchEvent处理如1,以后交给onTouchEvent)

* 而LayoutView1都还是要经过onInterceptTouchEvent(见LayoutView1的4,6,8)

*

* 4.如果最终需要处理事件的view的onTouchEvent()返回了false(没能处理这个事件,不能丢在传回来让父继续),

* 那么该事件将被传递至其上一层次的view的onTouchEvent()处理。

* **************************************************************************

* 感觉像是一个圈,然后一直在找一个能处理这个消息的人,如果找到了就结束,没找到就循环,直到回到发出消息的那个人

* 注(对下面):没有标注的DOWN表示拦截事件onInterceptTouchEvent,标注了onTouchEvent就是处理事件

* a.如果都没处理(onInterceptTouchEvent返回false):

A(DOWN)-->B(DOWN)-->C(onTouchEvent DOWN)-->B(onTouchEvent DOWN)-->A(onTouchEvent DOWN),没有执行UP事件,注意有MOVE的话,在DOWN和UP之间,下面的都一样。

*b. B处理(B的onInterceptTouchEvent返回true):

A(DOWN)-->B(DOWN)-->B(onTouchEvent)-->A(onTouchEvent UP)-->B(onTouchEvent UP)-->(over)

*

形象说明:如果父亲不拦截消息就传给儿子,如果儿子要这个消息就处理(DOWN),结束,然后有父亲1--父亲2--儿子以此释放消息(UP)。 然是如果儿子对这个消息置之不理,那这个消息又传回父亲,由父亲来处理即。

下面给出了5中情况(不拦截表示onInterceptTouchEvent返回false):

* 11** 父亲1(LayoutView1不拦截false)---父亲2(LayoutView2不拦截false)--儿子(MyTextView,onTouchEvent return true)--结束

* 22** 父亲1(LayoutView1不拦截false)---父亲2(LayoutView2不拦截false)--儿子(MyTextView,onTouchEvent return false)--回传给父亲2(onTouchEvent return true)--结束

* 33** 父亲1(LayoutView1不拦截false)---父亲2(LayoutView2不拦截false)--儿子(MyTextView,onTouchEvent return false)--回传给父亲2(onTouchEvent return false)--父亲1(onTouchEvent return true)--结束(如果都没处理不在执行UP ACTION)

* 44** 父亲1(LayoutView1拦截true)--父亲1(onTouchEvent return true)--结束          (DOWN--DOWN(onTouchEvent)--UP(onTouchEvent))

* 55** 父亲1(LayoutView1拦截false)--父亲2(LayoutView2拦截true)--父亲2(onTouchEvent return false)--父亲1(onTouchEvent return true)--结束      (DOWN1--DOWN2--DOWN(2 onTouchEvent)--DOWN(1 onTouchEvent)--UP(1 onTouchEvent))(1:父亲2,2:父亲2)

*

* ***************************************************************************

* 5.如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。

*/

流程图

时间: 2024-11-08 19:00:25

android onInterceptTouchEvent onTouchEvent的相关文章

Android中dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的理解

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

android onInterceptTouchEvent和onTouchEvent的执行关系

DragHorizontalScrollView一.子布局没有自定义布局(只包含android原生布局)onInterceptTouchEvent不拦截 子布局可以点击-------onInterceptTouchEvent不拦截 part1---------onTouchEvent不接收 I/>>lilei>>DragHorizontalScrollView(23283): ****return false onInterceptTouchEvent 222 action:ACT

Android dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent详解

之前遇到事件分发,去网上找相关文章...感觉都没把这几个的关系说明白.研究了几篇不错的文章,今天在这整理一下,希望对大家有所帮助. 首先你要知道一点,当你触摸一个控件的时候,你就会调用该控件(或它的父类)的dispatchTouchEvent方法.那我们就来看一下dispatchTouchEvent方法的源码: public boolean dispatchTouchEvent(MotionEvent event) { if (mOnTouchListener != null && (mV

onInterceptTouchEvent onTouchEvent 的坑 坑死了

简单来说,不想研究这个,坑死了. onInterceptTouchEvent 是从父级向子级传递. onTouchEvent 是从子级向父级传递. 它们两个相互不影响,onInterceptTouchEvent 先触发,onTouchEvent 后触发. onInterceptTouchEvent 是ViewGroup的事件. onTouchEvent 是View 的事件,如果一个View 不能再包含子View ,则它没有 onInterceptTouchEvent 事件. 事件触发顺序为 Mo

dispatchTouchEvent onInterceptTouchEvent onTouchEvent区分

  1. dispatchTouchEvent 是处理触摸事件分发,执行super.dispatchTouchEvent(ev),事件向下分发.   2. onInterceptTouchEvent是ViewGroup提供的方法,默认返回false,返回true表示拦截. 3. onTouchEvent是View中提供的方法,ViewGroup也有这个方法,view中不提供onInterceptTouchEvent.view中默认返回true,表示消费了这个事件.

DispatchTouchEvent &amp; OnInterceptTouchEvent &amp; onTouchEvent的含义和区别

1.DispatchTouchEvent Pass the touch screen motion event down to the target view, or this view if it is the target. 传递触摸事件到目标视图,或者他就是目标视图. 情况1:return true 则事件只会在当前方法内消耗掉,且不会向下传递,最后传给Activity. 情况2:return false   则事件只会在当前方法内消耗且不会向下传递,最后传给Activity. 但是不同于

Android中onTouchEvent, onClick及onLongClick的调用机制(二)

android应用中常用的监听OnTouchListener.OnClickListener.OnLongClickListener,大家肯定经常使用.但是你真的知道它会产生的神奇效果么?不要忽视这些神奇效果哦!说不定这些神奇效果正是你想要的呢?好,下面请看我的示例. 示例. 首先在Activity中创建一个button,然后对这个button同时设置OnTouchListener.OnClickListener.onLongClickListener这三种监听方式.接着就是重写这三个接口的实现

Android中事件传递机制的总结

事件传递虽然算不上某个单独的知识点,但是在实际项目开发中肯定会碰到,如果不明白其中的原理,那在设计各种滑动效果时就会感到很困惑. 关于事件的传递,我们可能会有以下疑问: 事件是如何传递的 事件是如何处理的 自定义view的时候,事件也冲突了怎么解决 带着这三个疑问,我们来总结一下事件传递机制是怎么回事. 一.事件分发的原理: 1.事件是如何传递的: (1)首先由Activity分发,分发给根View,也就是DecorView(DecorView为整个Window界面的最顶层View) (2)然后

Android事件分发机制

转载请注明出处:http://blog.csdn.net/chziroy/article/details/44401615 要理解Android事件分发机制,首先得了解几个概念,也算是总结,如果暂时看不懂也无妨,本文会讲解这几个问题. 1,点击屏幕,首先事件的传递从Activity的dispatchTouchEvent()方法开始. 2,关于Android事件分发机制,相关方法的方法有三个:onTouchEvent(),dispatchTouchEvent(),还有onInterceptTouc