閱讀目錄
1.View的事件分發機制2.ViewGroup的事件分發機制回到頂部一個button,簡單一點就是onTouch,還有onclick事件,我們一個一個來分析
首先響應的是dispatchTouchEvent

public boolean dispatchTouchEvent(MotionEvent event) { if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && mOnTouchListener.onTouch(this, event)) { return true; } return onTouchEvent(event); }
其實,在android源碼的命名還是很有規律的,dispatchXXX,也就是分發機制,往往就是第一個需要響應的地方。
我們來分析下:touchlistener不為空,也就是view的使用者設置了回調。
第二個條件就是View必須是enable的。第三:onTouch返回false,就說明onTouch不消費該事件,由OnTouchEvent響應。
如果返回True,那么就會直接return。
所以onClick事件一定會被調到。
onTouchEvent最終會走到performClick這個方法。

public boolean performClick() { final boolean result; final ListenerInfo li = mListenerInfo; if (li != null && li.mOnClickListener != null) { playSoundEffect(SoundEffectConstants.CLICK); li.mOnClickListener.onClick(this); result = true; } else { result = false; } sendaccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); return result; }
可以看到,如果setOnClickListener, onClick 就會走到。
回到頂部2.ViewGroup的事件分發機制

<com.joyfulmath.frameworksample.viewdemo.MyLayout android:id="@+id/my_layout" android:background="#99000044" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:id="@+id/button_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button"/> <Button android:id="@+id/imageId" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@android:drawable/ic_lock_power_off"/> </com.joyfulmath.frameworksample.viewdemo.MyLayout>
一個layout里面有2個button,
TestViewAction
分別點擊button1 & button2 & 灰色部分
等到log如下:

08-27 10:19:26.799 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.880 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.896 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.913 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.926 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: button_id [at (TestViewAction.java:55)]08-27 10:19:26.926 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onClick: button_id [at (TestViewAction.java:38)]08-27 10:19:27.434 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: imageId [at (TestViewAction.java:58)]08-27 10:19:27.535 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: imageId [at (TestViewAction.java:58)]08-27 10:19:27.543 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: imageId [at (TestViewAction.java:58)]08-27 10:19:27.544 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onClick: imageId [at (TestViewAction.java:41)]08-27 10:19:28.111 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.156 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.173 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.190 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.237 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onTouch: my_layout [at (TestViewAction.java:61)]08-27 10:19:28.237 2120-2120/com.joyfulmath.frameworksample I/TestViewAction: onClick: my_layout [at (TestViewAction.java:44)]
也就是點擊button1以后,不會傳遞都layout
But,如果layout里面有一個函數
public boolean onInterceptTouchEvent(MotionEvent ev)這個函數就是截斷對button的分發處理,默認是return false。
至此,我們有了一個大概的流程。
Activtiy->ViewGroup->View
如果仔細分析就會發現,在Activity里面有一個getDocView。所以Activity里面有個RootView的概念。
言歸正傳,ViewGroup本質上也是一個View,所以,可以把模型簡單的定性為Activtiy->ViewGroup->View 三層。
首先Activity里面有2個函數,我們分析看看:

@Override public boolean dispatchTouchEvent(MotionEvent ev) { TraceLog.i(); return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { TraceLog.i(); return super.onTouchEvent(event); }
所以大體流程如下:
1.@Activty.diapatchTouchEvent ->@Layout.dispatchTouchEvent->@layout.onInterceptTouchEvent return true/false
2.return true->@layout.onTouchEvent 后面部分同view
3.return false->@view.dispatchTouchEvent View的分發見上一片流程。
參考:
《深入理解android設計思想》 林學森
轉載地址:http://www.cnblogs.com/deman/p/5812570.html
新聞熱點
疑難解答