編輯:Android編程入門
1 事件的傳遞順序是 Activity -> Window -> 頂層View
touch 事件產生後,最先由 activity 的 dispatchTouchEvent 處理
/** * Called to process touch screen events. You can override this to * intercept all touch screen events before they are dispatched to the * window. Be sure to call this implementation for touch screen events * that should be handled normally. * * @param ev The touch screen event. * * @return boolean Return true if this event was consumed. */ public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); }
接著事件會傳到 Window 的 superDispatchTouchEvent。 如果所有的 view 都沒有消費事件,最後會交給 activity 的 onTouchEvent 處理。
2 Window 是一個抽象類,它的唯一實現類是 PhoneWindow
/** * Abstract base class for a top-level window look and behavior policy. An * instance of this class should be used as the top-level view added to the * window manager. It provides standard UI policies such as a background, title * area, default key processing, etc. * * <p>The only existing implementation of this abstract class is * android.view.PhoneWindow, which you should instantiate when needing a * Window. */ public abstract class Window {
}
查看 PhoneWindow 的 superDispatchTouchEvent
public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); }
調用了 mDecor 的 superDispatchTouchEvent
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {} // This is the top-level view of the window, containing the window decor. private DecorView mDecor;
mDecor 就是 DecorView, DecorView 是一個 FrameLayout, 就是我們 setContentView 所設置 view 的父容器。
繼續看 DecorView 的superDispatchTouchEvent
public boolean superDispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); }
調用了父類的 dispatchTouchEvent, FrameLayout 中沒有 dispatchTouchEvent, 實際上調用了 FrameLayout 的父類 ViewGroup 的 dispatchTouchEvent。
到此事件就傳遞到了頂層View(ViewGroup) 中,接著事件就從頂層 view 開始向子view分發。
3 事件分發主要涉及 3 個方法
public boolean dispatchTouchEvent(MotionEvent event)
事件傳遞到一個 view 時就會先調用這個 view 的 dispatchTouchEvent 進行往下分發
public boolean onInterceptTouchEvent(MotionEvent ev)
進行事件的攔截,只有 ViewGroup 有攔截方法, 單一View沒有,事件傳到 單一View 就直接調用 onTouchEvent 進行處理了
public boolean onTouchEvent(MotionEvent event)
處理點擊事件,true 表示消費這個事件, false 表示不消費
4 下面的偽代碼可以很好的說明事件的分發過程
public boolean dispatchTouchEvent(MotionEvent ev) { boolean consume = false; if (onInterceptTouchEvent(ev)) { consume = onTouchEvent(ev); }else { consume = child.dispatchTouchEvent(ev); } return consume; }
事件傳遞到頂層 ViewGroup 中後, 就會調用 ViewGroup dispatchTouchEvent 進行分發。如果這個 ViewGroup 的 onInterceptTouchEvent 返回 True 表是它要攔截這個事件,接著就會調用它的 onTouchEvent 進行處理。如果不攔截則會交給它的子 view 繼續進行分發, 如此反復直到事件被最終處理。
正常情況下,一個事件序列只能被一個 view 攔截且消耗。一個 view 一旦攔截了某個事件,那麼同一個事件序列內的所有的事件都會交給它處理。
如果一個 view 的 onTouchEvent 返回 false, 那麼它的父容器的 onTouchEvent 將會被調用,依次類推。如果所有的 view 都不處理這個事件,這個事件最後會返回到 activity 的 onTouchEvent 進行處理。
事件分發具體細節較為復雜,但基本流程就是上面的偽代碼。事件分發機制是處理滑動沖突的根本,知道了原理,遇到問題再多看看源碼就行了。
Android Hello World 實例讓我們開始真正的基於Android框架編程。在開始使用Android SDK寫第一個示例之前,請確保你已經按照
Android項目具有其自身的結構規范,完好的遵循結構規范,可以讓開發事半功倍。下圖分別從Android視圖和Project視圖展示了Android項目的項目結構:圖中左
PS:眼看就要開學了,該收收心了. 學習內容:1.ConnecivityManager2.NetWorkInfo Connectivit
這個月裝逼有點少了,為什麼呢,因為去考軟件射雞師了,快到兒童節了,趕緊寫篇博紀念一下逝去的青春,唔,請忽略這句話。 二維碼其實有很多種,但是我們常見的微信使用的