版權(quán)聲明:本文來自門心叼龍的博客儡羔,屬于原創(chuàng)內(nèi)容真仲,轉(zhuǎn)載請注明出處:https://blog.csdn.net/geduo_83/article/details/90145083
github源碼下載地址:https://github.com/geduo83/android-touch-event
Android事件分發(fā)機制的探索與發(fā)現(xiàn)之View篇
Android事件分發(fā)機制的探索與發(fā)現(xiàn)之ViewGroup篇
Android事件分發(fā)機制的探索與發(fā)現(xiàn)之Activity篇
Android事件分發(fā)機制的探索與發(fā)現(xiàn)之總結(jié)篇
Android事件分發(fā)機制在實戰(zhàn)開發(fā)中的應(yīng)用之一
Android事件分發(fā)機制在實戰(zhàn)開發(fā)中的應(yīng)用之二
上一篇文章我們主要講View MyButton的事件分發(fā)流程,這篇主要來分析MyLayout的事件分發(fā)流程,研究方法一樣,通過改變返回值,來觀察事件的分發(fā)流程
MyLayout的onInterceptTouchEvent方法
MyLayout其本質(zhì)是一個ViewGroup铁坎,ViewGroup比View就多了一個事件攔截的方法onInterceptTouchEvent,因此我們MyLayout對的測試先從它的攔截方法開始
- 情況1:調(diào)用父類的同名方法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return super.onInterceptTouchEvent(ev);
}
其實我們上面已經(jīng)測試過了犁苏,我們的測試MyButton的相關(guān)方法的時候硬萍,MyLayout的onInterceptTouchEvent方法調(diào)用的就是父類的同名方法,
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyButton dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
事件到達MyLayout onInterceptTouchEvent的方法后围详,調(diào)用了父類的同名方法super.onInterceptTouchEvent后朴乖,事件會繼續(xù)傳遞給MyButton的dispatchTouchEvent 方法進行事件分發(fā)
- 情況2:返回false
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return false;
}
點擊測試結(jié)果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyButton dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyButton onTouchEvent start:ACTION_DOWN
----------------------------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_UP
V/MYTAG: MyButton dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyButton onTouchEvent start:ACTION_UP
我們發(fā)現(xiàn)MyLayout的onInterceptTouchEvent方法返回false和調(diào)用父類的同名方法super.onInterceptTouchEvent方法,事件的傳遞流程都是一樣的
- 情況3:返回ture
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return super.onTouchEvent(event);
}
點擊測試結(jié)果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
--------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
如果返回true觸摸事件不會繼續(xù)傳遞給MyButton了助赞,而直接就被MyLayout攔截掉了,并將事件傳遞給自己的onTouchEvent方法進行消費
好了买羞,關(guān)于MyLayout的onInterceptTouchEvent方法我們徹底測試完畢了,我們不難得出結(jié)論:當(dāng)onInterceptTouchEvent返回false和調(diào)用父類的同名方法的時候雹食,觸摸事件會繼續(xù)往下傳遞畜普,當(dāng)返回true的時候該事件就被被攔截掉,并交給自己的onTouchEvent方法進行處理
MyLayout的onTouchEvent方法
- 情況1:調(diào)用父類的同名方法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return super.onTouchEvent(event);
}
注意了群叶,為了便于測試我們讓onInterceptTouchEvent返回true
測試結(jié)果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
--------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
通過測試日志我們可以發(fā)現(xiàn)吃挑,當(dāng)MyLayout的onTouchEvent調(diào)用父類的同名方法钝荡,觸摸事件會繼續(xù)回傳給MainActivity的onTouchEvent進行處理,其實在前面我們測試過了舶衬,當(dāng)MyButton的onTouchEvent方法返回false和dispathTouchEvent方法返回false觸摸事件都會回傳給MyLayout的onTouchEvent方法埠通,緊接著就繼續(xù)回傳給MainActivity的onTouchEvent方法
- 情況2:返回false
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return false;
}
測試結(jié)果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
---------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_MOVE
V/MYTAG: MainActivity onTouchEvent start:ACTION_MOVE
---------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
返回false和調(diào)用父類的同名方法,事件傳遞的流程都是一樣的逛犹,觸摸事件都回傳給了MainActivity的onTouchEvent方法進行處理
- 情況3:返回true
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout onInterceptTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v(TAG,"MyLayout onTouchEvent start:"+MotionEventUtil.getMotionEventName(event));
return true;
}
測試結(jié)果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
----------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout onTouchEvent start:ACTION_UP
返回true很簡單植阴,事件被自己消費掉了
好了,截止到線程關(guān)于MyLayout的onTouchEvent方法就分析完畢了圾浅,我們不難得出結(jié)論:MyLayout的onTouchEvent方法返回true事件就消費掉了,如果返回false和調(diào)用父類的同名方法super.onTouchEvent方法事件就會繼續(xù)回傳給MainActivity的onTouchEvent方法進行處理
MyLayout的dispatchTouchEvent方法
- 情況1:調(diào)用父類的同名方法
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout dispatchTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return super.dispatchTouchEvent(ev);
}
上面也都測試過了憾朴,如果MyLayout的dispatchTouchEvent調(diào)用了父類的同名方法則觸摸事件會繼續(xù)傳遞給它自己的onInterceptTouchEvent方法進行處理,測試日志如下:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onInterceptTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout onTouchEvent start:ACTION_DOWN
- 情況2:返回false
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout dispatchTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return false;
}
點擊測試:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MainActivity onTouchEvent start:ACTION_DOWN
--------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MainActivity onTouchEvent start:ACTION_UP
返回false觸摸事件直接就回傳了給了MainActivity的onTouchEvent方法進行處理了
- 情況3:返回true
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.v(TAG,"MyLayout dispatchTouchEvent start:"+MotionEventUtil.getMotionEventName(ev));
return true;
}
點擊測試結(jié)果:
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_DOWN
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_DOWN
----------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_MOVE
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_MOVE
----------------------------------------------------------
V/MYTAG: MainActivity dispatchTouchEvent start:ACTION_UP
V/MYTAG: MyLayout dispatchTouchEvent start:ACTION_UP
返回true狸捕,觸摸事件就直接被自己的dispatchTouchEvent方法消費掉了
好了,截止目前關(guān)于MyLayout的dispathTouchEvent方法就徹底分析完畢了众雷,結(jié)論如下:MyLayout的dispatchTouchEvent方法調(diào)用父類的同名方法則事件會繼續(xù)往下傳遞給自己的onInterceptTouchEvent方法灸拍,如果返回false則事件會回傳給MainActivity的onTouchEvent方法進行處理,如果返回為true則就自行消費掉了