轉帖|使用教程|編輯:我只采一朵|2014-03-10 14:20:39.000|閱讀 281 次
概述:本文詳細介紹了Android界面開發中要遇到的事件模型,及Android事件交互,幫助你寫出具有出色交互功能的應用。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
一般我們處理事件,都是針對某一個View來處理的,要么是添加onTouchListener監聽器,要么繼承View然后重寫View#onTouchEvent,甚至不用重寫,只要使用Widget自己的監聽函數 ,或者GestureDetector就OK了。但是理解Android事件模型,對于理解GestureDetector,及Android事件的交互,寫出具有出色的交互的應用,都是必經之路。
一:ViewGroup與View的事件模型
我們都知道Android界面實際是一棵View的樹。枝干是ViewGroup。ViewGroup繼承自View,但是又是管理View的容器。那么ViewGroup與View的事件關系是怎么樣的呢?
這需要從另一個重要的ViewGroup中的方法,如下說起:
public boolean onInterceptTouchEvent(MotionEvent ev) { return false; }
它的默認實現很簡單,就是把事件交給子View去處理,自己不攔截,Intercept就是攔截的意思。此方法的注釋,對于ViewGroup與View的事件模型說得很清楚。
主要是以下幾點:
(1) 如果此方法返回false,說明此ViewGroup暫時(只是暫時)對于觸控事件不感興趣。
但是不知道后面的事件它感不感興趣。所以后續事件還會一直傳遞到此方法中來,供此方法判斷。
(2) 如果此方法返回true了。那么說明此方法對應的ViewGroup開始對于此事件(或者手勢)感興趣了。
那么后續事件就會直接給此方法對應的ViewGroup的onTouchEvent方法來處理事件了。
(3) 如果此方法一開始返回false,說不感興趣這個時候事件發給了目錄View。
現在又返回true,說感興趣了。那么目錄View就會收到一個action為ACTION_CANCEL的事件。
跟此方法返回true時的事件是同一個事件 ,只是action變了。
(4) ViewGroup會在這里接收觸控開始的事件。
規則就是上面這些 ,那么是誰在后面處理這些規則呢?就是ViewGroup。它在disptachTouchEvent方法中,進行了一系列的處理來實現這種模型。
public boolean dispatchTouchEvent(MotionEvent ev)
對于單獨的View本身來說,它也有一個簡單的事件派發模型。通過以下代碼就可以很明白的看出來了:
View#dispatchTouchEvent(MotionEvent event):
ListenerInfo li = mListenerInfo; if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { return true; } if (onTouchEvent(event)) { return true; }
二: Activity與View的事件模型
事件先到Activity中,然后Activity調用:
/** * 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); }
先讓用戶界面窗口處理:getWindow()。superDispatchTouchEvent(ev)。如果窗口沒有處理這個事件,那就交給Activity自己處理。return onTouchEvent(ev)
這個Window跟View層級是怎么交互的呢?
我們找到了Window的實現類:PhoneWindow(com.android.internal.policy.impl.PhoneWindow)
@Override public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); }
這個mDecor就是用戶界面的根View了。
private final class DecorView extends FrameLayout
(com.android.internal.policy.impl.PhoneWindow.DecorView)
原來窗口將事件交給根View來進行事件派發的。mDecor調用自己的superDispatchTouchEvent(event),然后將事件派發的任務交給了自己的dispatchTouchEvent。
public boolean superDispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); }
這里調用的super.dispatchTouchEvent 就是ViewGroup的聲明的dispatchTouchEvent的了.
本文轉載自//my.oschina.net/banxi/blog/187178
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:oschina