View的事件分發(fā)機(jī)制
在android中鸟蜡,點(diǎn)擊的事件分發(fā)就是對(duì)MotionEvent的分發(fā),當(dāng)一個(gè)點(diǎn)擊事件產(chǎn)生后,傳遞過(guò)程應(yīng)該是:Activity->Window->DecorView->CustomView渤刃。
事件分發(fā)這個(gè)過(guò)程由三個(gè)重要方法來(lái)完成:
1. public boolean dispatchTouchEvent(MotionEvent event)
用于進(jìn)行事件的分發(fā)宠默。如果事件能傳遞到當(dāng)前View用狱,此方法必定會(huì)被調(diào)用运怖,返回結(jié)果受當(dāng)前View的onTouchEvent和下級(jí)View的dispatchTouchEvent方法影響。
- true 消費(fèi)事件夏伊。
- false 不向下分發(fā)事件摇展,交由上層控件的onTouchEvent消費(fèi)。如果當(dāng)前控件為Activity溺忧,那么事件會(huì)被系統(tǒng)消費(fèi)咏连。
- super.dispatchTouchEvent(event) 交給本層控件的onInterceptTouchEvent處理。
2. public boolean onInterceptTouchEvent(MotionEvent ev)
在dispatchTouchEvent方法內(nèi)部調(diào)用鲁森,此方法只存在ViewGroup中祟滴。表示是否攔截事件。攔截時(shí)只會(huì)調(diào)用一次歌溉。
- true 攔截事件垄懂,本層onTouchEvent處理。
- false 不攔截痛垛,分發(fā)到子View草慧。由子View的dispatchTouchEvent處理。
- super.onInterceptTouchEvent(event) 默認(rèn)為不攔截任何事件匙头。
3. public boolean onTouchEvent(MotionEvent event)
在dispatchTouchEvent方法內(nèi)部調(diào)用漫谷,用于處理點(diǎn)擊事件。
- true 表示處理完事件后消費(fèi)掉乾胶。
- false 不處理事件抖剿,交由上層View的onTouchEvent方法處理朽寞,如果一直返回false直到Activity识窿,那么由Activity的onTouchEvent處理。
- super.onTouchEvent(event) 如果此View為可點(diǎn)擊的脑融,默認(rèn)返回true喻频。
下面用代碼解釋以下幾種情況:
- 默認(rèn)情況。
- ViewGroup攔截事件肘迎,即onInterceptTouchEvent返回true甥温。
- 子View的onTouchEvent返回false,則會(huì)往上分發(fā)妓布。
- 解釋?zhuān)耗J(rèn)情況下姻蚓,從Activity->ViewGroup->View分發(fā)到子View上的onTouchEvent上消費(fèi)。
- 解釋?zhuān)涸赩iewGroup上攔截事件匣沼,即onInterceptTouchEvent返回true狰挡。除了在DOWN的時(shí)候調(diào)用了一次onInterceptTouchEvent外,后面的MOVE和UP都沒(méi)有再次調(diào)用,說(shuō)明攔截方法在同一觸摸事件中只執(zhí)行一次加叁。
ViewGroup的onTouchEvent默認(rèn)不消費(fèi)倦沧,所以向上分發(fā)到Activity的onTouchEvent中消費(fèi)。
- 解釋?zhuān)涸赩iewGroup不攔截也不消費(fèi)的情況下它匕,子View的onTouchEvent也不消費(fèi)展融,那么會(huì)向上分發(fā),一直到Activity才被消費(fèi)豫柬。