學習資料:
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處理。