Android触摸事件传递机制学习笔记
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() 方法。
如果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。
更多相关文章
- Android:Activity中onCreate方法的参数及用途
- 最新Android 7.1.1 截屏方法
- Android 防止在N秒内产生多次点击事件(干货)
- Android 手势&触摸事件 MotionEvent
- Android应用程序四种数据存取方法总结
- Android中的双击事件,GestureDetector无效的原因
- traceview的使用方法
- android Bimtap 各种图片处理方法、图片特效
- 触摸事件的机制