学习资料:
1.Understanding Android Input Touch Events System Framework
2.Managing Touch Events in a ViewGroup
3.Android事件传递机制
4.Input Events
5.Mastering the Android Touch System
6.MotionEventhtml
用户每次触摸屏幕都被包装成了MotionEvent(运动事件)对象。java
属性有:android
ACTION_DOWN
,ACTION_UP
等等,用于描述用户当前的动做。View的事件分发,就是对MotionEvent事件的分发过程。程序员
事件分发的三个重要方法:ide
//用于分发事件(dispatch touch event),要么将事件向下传递到目标View,要么交由本身处理。 //返回true表示本身处理 public boolean dispatchTouchEvent (MotionEvent event) //用于拦截事件(intercept touch event),ViewGroup中有,View中没有这个方法。 public boolean onInterceptTouchEvent (MotionEvent event) //用于处理事件 public boolean onTouchEvent (MotionEvent event)
三个方法的关系可用以下伪代码描述:学习
public boolean dispatchTouchEvent(MotionEvent ev){ boolean consume = false; if(onInterceptTouchEvent(ev)){ consume = true; }else{ consume = child.dispatchTouchEvent(ev); } return consume; }
View的onTouchListener
的优先级比onTouchEvent
方法的高。ui
运动事件的传递顺序:spa
Activity-->Window-->View
下面是将View
的dispatchTouchEvent()
方法设置断点后,点击ImageView
的调试过程:调试
能清楚地看到事件的传递过程和顺序。code
若View的onTouchEvent()
方法返回false,则会调用它的父View的onTouchEvent()
方法,依此类推,若调用顺序上的全部View都不处理这个事件,则这个事件会最终传递给Activity的onTouchEvent()
方法。
View的事件分发机制相似于互联网公司的工做流程:
新任务: CEO-->产品经理-->CTO-->开发小组组长-->程序员 由上至下一级一级分发任务(dispatchTouchEvent),若是是本身的任务(onInterceptTouchEvent) ,则拦截本身处理(onTouchEvent),反之,则交由下级分发(child.dispatchTouchEvent)。 若是事情搞不定,就一级一级向上抛(parent.onTouchEvent): 程序员-->开发组长-->CTO-->产品经理-->CEO
事件传递机制的一些结论:
onInterceptTouchEvent()
方法默认返回falseonInterceptTouchEvent()
方法requestDisallowInterceptTouchEvent()
方法能够在子元素中干预父元素的事件分发过程。Activity
,而后由Activity
的dispatchTouchEvent()
方法进行事件的分发。Activity会将事件交由window进行分发。//Activity源码 ... /* * Activity的dispatchTouchEvent方法 */ public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { onUserInteraction(); } //Activity交由window进行事件分发 if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); }
Activity.getWindow().getDecorView()
方法获取)。而Window类是抽象类,superDispatchTouchEvent()
方法是抽象方法。//Window类是抽象类 public abstract class Window { ... //window的superDispatchTouchEvent方法是抽象方法 public abstract boolean superDispatchTouchEvent(MotionEvent event); ... }
而PhoneWindow类是Window类的惟一实现类。
public class PhoneWindow extends Window implements MenuBuilder.Callback { ... @Override public boolean superDispatchTouchEvent(MotionEvent event) { //PhoneWindow直接将事件交友DecorView处理 return mDecor.superDispatchTouchEvent(event); } ... }
能够看到PhoneWindow类在实现抽象方法superDispatchTouchEvent
时,直接将事件交由DecorView处理。