Android—View事件分发与View子类
View的事件分發
4個操作:
- DOWN: 當用戶手指按下時
- MOVE: 當用戶開始滑動時
- UP: 用戶抬起手指
- CANCEL: 取消操作,事件被無法到達時
3個方法:
- dispatchTouchEvent()? ? ? ? ? 負責將事件分發到其子View或當前View中
- onInterceptTouchEvent()? ? ?僅存在與ViewGroup中,用于攔截點擊事件
- onTouchEvent()? ? ? ? ? ? ? ? ?? 完成對點擊事件的處理,消耗事件。
事件的傳遞順序是 DecorView?-> 子View/ViewGroup
事件發生在Activity先調用?getWindow().superDispatchTouchEvent(ev),如果返回true,那么事件被消費。如果返回false表示事件發下去卻沒有View可以進行處理,則最后return Activity自己的onTouchEvent方法。
public boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {onUserInteraction();}if (getWindow().superDispatchTouchEvent(ev)) {return true;}return onTouchEvent(ev);}PhoneWindow,PhoneWindow又回調DecorView的dispatchTouchEvent,所以事件從DecorView向下傳。
class PhoneWindow// This is the top-level view of the window, containing the window decor.private DecorView mDecor;public boolean superDispatchTouchEvent(MotionEvent event) {return mDecor.superDispatchTouchEvent(event);}頂層 ViewGroup 的dispatchTouchEvent方法里:
- 如果這個 ViewGroup 的?onInterceptTouchEvent 返回 true 表示它要攔截這個事件,接著就會調用它的 onTouchEvent 進行處理。
- 如果不攔截則會交給它的子 view 繼續進行分發, 如此反復直到事件被最終處理。
onInterceptTouchEvent()是ViewGroup的一個方法,目的是在系統向該ViewGroup及其各個childView觸發onTouchEvent()之前對相關事件進行一次攔截.
down事件首先會傳遞到onInterceptTouchEvent()方法
如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之后return false,那么后續的move, up等事件將繼續會先傳遞給該ViewGroup,之后才和down事件一樣傳遞給最終的目標view的onTouchEvent()處理。
如果該ViewGroup的onInterceptTouchEvent()在接收到down事件處理完成之后return true,那么后續的move, up等事件將不再傳遞給onInterceptTouchEvent(),而是和down事件一樣傳遞給該ViewGroup的onTouchEvent()處理,注意,目標view將接收不到任何事件。
如果最終需要處理事件的view的onTouchEvent()返回了false,那么該事件將被傳遞至其上一層次的view的onTouchEvent()處理。
如果最終需要處理事件的view 的onTouchEvent()返回了true,那么后續事件將可以繼續傳遞給該view的onTouchEvent()處理。
onTouchEvent() 用于處理事件,返回值決定當前控件是否消費(consume)了這個事件。比如ACTION_MOVE或者ACTION_UP發生的前提是一定曾經發生了ACTION_DOWN,如果你沒有消費ACTION_DOWN,那么系統會認為ACTION_DOWN沒有發生過,所以ACTION_MOVE或者ACTION_UP就不能被捕獲。
ViewGroup里的onInterceptTouchEvent默認值是false這樣才能把事件傳給View里的onTouchEvent.
ViewGroup里的onTouchEvent默認值是false,后續MOVE和UP事件不會傳遞過來。
View里的onTouchEvent返回默認值是true.這樣才能執行多次touch事件。
在View中常用的兩個方法OnTouch和OnClick
在dispatchTouchEvent中,會首先判斷OnTouchListener是否為空,如果設置了onTouchListener,那么OnTouchListener方法中的onTouch方法會被回調。onTouch方法返回true,則onTouchEvent方法不會被調用(onClick事件是在onTouchEvent中調用),否則會直接執行onTouchEvent事件。
dispatchTouchEvent -> onTouch(setOnTouchListener) -> onTouchEvent -> onClick
每個activity都對應一個窗口window,這個窗口是PhoneWindow的實例,PhoneWindow對應的布局是DecorView,是一個FrameLayout,DecorView內部又分為兩部分,一部分是ActionBar,另一部分是ContentParent,即activity在setContentView對應的布局。
總結
以上是生活随笔為你收集整理的Android—View事件分发与View子类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10个管理工作时间的小技巧
- 下一篇: 10岁起编程,并不认为自己是“黑客”