1、Android 触摸事件传递机制
http://blog.csdn.net/awangyunke/article/details/22047987
2、Android-onInterceptTouchEvent()和onTouchEvent()总结
http://blog.csdn.net/lvxiangan/article/details/9309927
3、Android onTouchEvent, onClick及onLongClick的调用机制
http://blog.csdn.net/ddna/article/details/5451722
4、Android: 详解触摸事件如何传递
http://www.cnblogs.com/superlcr/p/3946034.html?utm_source=tuicool
一、涉及的类和方法
Activity,View,ViewGroup(View的子类)
1)public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent,在Activity和View里分别定义
这个方法尝试将触摸事件交给自己的子视图 (如果有的话) 处理: 调用子视图的 dispatchTouchEvent()
或者自己处理: 调用自己的 onTouchEvent() 或 OnTouchListener.onTouch()(优先调用)
无论是自己的子视图,还是自己,只要完成了事件处理,都返回 true
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
ViewGroup单独定义的方法,如果事件需要在该 ViewGroup 截断 (自己处理该事件, 不再传递给其子视图), 则返回 true
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent 在Activity和View里分别定义
这个方法尝试自己处理触摸事件. 如果完成处理 (不需要再交给其他 View 处理), 则返回 true
二,传递流程
从Activity的dispatchTouchEvent开始,这是触摸事件的入口,没有重写的情况下会无条件的传递给根视图ViewGroup的dispatchTouchEvent,经过如下图的流程,返回true表示ViewGroup消费了事件,返回false则返回Activity自己的 onTouchEvent() 方法。

Android触摸事件传递机制学习笔记_第1张图片

如果ViewGroup 还有子视图,且仍然没有截断的话,会继续调用子视图的子视图,如此递归进行。触摸事件派遣的顺序是自上而下的。直到到达某个叶子 View (不再有子视图可以派遣),或者某个 ViewGroup 虽然还有子视图可以派遣,但其截断 onInterceptTouchEvent() 方法返回 true。这时,触摸事件真正开始尝试进行处理。

处理方法:如果注册了触摸事件监听器 OnTouchLisener,则优先调用 OnTouchLisener.onTouch() 方法,如果没有注册监听器,或OnTouchLisener.onTouch() 方法返回 false,再尝试调用 ViewGroup 自身的 onTouchEvent() 方法

如果该 View 完成了触摸事件的处理 (返回 true),那么对于其父视图而言,dispatchTouchEvent() 方法派遣给子视图的事件圆满完成,可以向自己的父视图宣称完成事件了 (返回 true)。反之,如果该 View 自己没有完成触摸事件,对于其父视图 ViewGroup 而言,派遣子视图并没有完成事件处理,只好自己处理。如果再次没有完成,父视图会向自己的父视图返回 false,如果各层 ViewGroup 均不能完成事件处理,最终会调用 Activity 的 onTouchEvent() 方法,做最后的尝试。整个实际处理过程顺序正好相反,是自下而上的。

三、onClick、onLongClick和onTouchEvent
在 onTouchEvent() 中,会判断触摸是否构成一次点击事件,从而交给其他一些监听器,如 onClickListener (监听点击事件),onLongClickListener (监听长按事件) 来处理,同时返回 true。

onTouchEvent()方法的判断:

case MotionEvent.ACTION_DOWN:    mPrivateFlags |= PRESSED;    refreshDrawableState();    if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {         postCheckForLongClick(); //发起CheckForLongPress线程的执行,条件都满足后会设置OnLongClickListener    }    break;case MotionEvent.ACTION_UP:    if ((mPrivateFlags & PRESSED) != 0) {         boolean focusTaken = false;         if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {               focusTaken = requestFocus();         }    if (!mHasPerformedLongPress) {       if (mPendingCheckForLongPress != null) {             removeCallbacks(mPendingCheckForLongPress);       }       if (!focusTaken) {              performClick();//设置OnClickListener       }    }    …    break;

长按事件顺序:onTouch ACTION_DOWN——onLongClick——onTouch ACTION_UP
点击事件顺序:onTouch ACTION_DOWN——onTouch ACTION_UP——onClick

onLongClick的发生是在ACTION_UP之前,而onClick的发生是在ACTION_UP后,如果在onLongClick()方法的最后return true,则不会再触发onClick;如果return false的话会在ACTION_UP后仍然触发onClick。

更多相关文章

  1. Android:Activity中onCreate方法的参数及用途
  2. 最新Android 7.1.1 截屏方法
  3. Android 防止在N秒内产生多次点击事件(干货)
  4. Android 手势&触摸事件 MotionEvent
  5. Android应用程序四种数据存取方法总结
  6. Android中的双击事件,GestureDetector无效的原因
  7. traceview的使用方法
  8. android Bimtap 各种图片处理方法、图片特效
  9. 触摸事件的机制

随机推荐

  1. Android gdb调试
  2. ndk下使用sqlite
  3. Android Handler 消息机制原理解析
  4. android 2.3 r1 中文 api (58) —— TabH
  5. Android Handler机制1--ThreadLocal
  6. [入门八]Android的应用程序框架
  7. Android(安卓)使用MediaPlayer播放音乐
  8. 【Android热修复与插件化 三】ClassLoade
  9. Android系统关机或重启的几种实现方式
  10. 实现Android包的批量删除