理解一些事情
在ViewGroup(如LinearLayout、RelativeLayout等繼承ViewGroup的)中酬蹋,有下面三個(gè)方法:
dispatchTouchEvent 該方法用來分發(fā)事件
onInterceptTouchEvent 用來攔截事件
onTouchEvent 用來處理事件
而View(如Button糖声、TextView等繼承View的)中,只有兩個(gè)方法葵陵,即:
dispatchTouchEvent 該方法用來分發(fā)事件
onTouchEvent 用來處理事件
為什么View沒有onInterceptTouchEvent方法液荸?因?yàn)閂iew里面已經(jīng)不能再包含View了,不需要再處理攔截時(shí)間的分發(fā)脱篙。
例子
寫了個(gè)布局
<?xml version="1.0" encoding="utf-8"?>
<com.zyou.myapplication.ViewGroupA
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@android:color/holo_red_light">
<com.zyou.myapplication.MyView
android:id="@+id/btn_button"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@android:color/holo_blue_dark"/>
</com.zyou.myapplication.ViewGroupA>
紅色的就是ViewGroupA娇钱,藍(lán)色就是MyView。
并在View绊困、ViewGroupA文搂、ViewGroupB復(fù)寫方法,并加入LOG信息考抄。
public class ViewGroupA extends LinearLayout {
private final String TAG="fzy";
public ViewGroupA(Context context) {
super(context);
}
public ViewGroupA(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ViewGroupA(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d(TAG,"ViewGroupA onInterceptTouchEvent ");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d(TAG,"ViewGroupA dispatchTouchEvent ");
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG,"ViewGroupA onTouchEvent ");
return super.onTouchEvent(event);
}
}
現(xiàn)在來點(diǎn)擊中間黃色的MyView细疚,觀察下打印結(jié)果,如下:
MainActivity2 dispatchTouchEvent: 0
ViewGroupA dispatchTouchEvent: 0
ViewGroupA onInterceptTouchEvent: 0
MyView dispatchTouchEvent: 0
MyView onTouchEvent :0
ViewGroupA onTouchEvent: 0
MainActivity2 onTouchEvent: 0
MainActivity2 dispatchTouchEvent: 2
MainActivity2 onTouchEvent: 2
MainActivity2 dispatchTouchEvent: 2
MainActivity2 onTouchEvent: 2
MainActivity2 dispatchTouchEvent: 2
MainActivity2 onTouchEvent: 2
MainActivity2 dispatchTouchEvent: 1
MainActivity2 onTouchEvent: 1
可以看到我們當(dāng)touch的是MyView:
1. 首先處理事件分發(fā)的是MainActivity2的dispatchTouchEvent川梅,然后把事件往下傳遞給ViewGroupA疯兼。
2. 如果ViewGroupA的onInterceptTouchEvent沒有進(jìn)行攔截,則把事件傳給MyView贫途。
3. 由MyView的onTouchEvent進(jìn)行時(shí)間處理吧彪。如果方法都返回super.onTouchEvent,最后的ACITON_MOVE/ACTION_UP事件都不再經(jīng)過ViewGroupA和MyView丢早,而是直接在MainActivity2處理姨裸。
下面我們來測試一下,把ViewGroupA的onInterceptTouchEvent返回true怨酝,表示事件不再往下傳遞傀缩,即傳遞不到MyView了,表示ViewGroupA已經(jīng)處理农猬,不需要往下傳了赡艰,以下是LOG:
MainActivity2 dispatchTouchEvent: 0
ViewGroupA dispatchTouchEvent: 0
ViewGroupA onInterceptTouchEvent: 0
ViewGroupA onTouchEvent: 0
MainActivity2 onTouchEvent: 0
MainActivity2 dispatchTouchEvent: 2
MainActivity2 onTouchEvent: 2
MainActivity2 dispatchTouchEvent: 2
MainActivity2 onTouchEvent: 2
MainActivity2 dispatchTouchEvent: 2
MainActivity2 onTouchEvent: 2
MainActivity2 dispatchTouchEvent: 1
MainActivity2 onTouchEvent: 1
總結(jié)
用戶點(diǎn)擊屏幕,分發(fā)事件是由Activity–>ViewGroupA–>MyView走的斤葱,而onTouchEvent是從MyView–>ViewGroupA–>Activity慷垮,中途如果有onInterceptTouchEvent攔截事件揖闸,則dispatchTouchEvent不會(huì)往下傳遞,就回去了料身。整個(gè)過程有點(diǎn)像跳高汤纸,onInterceptTouchEvent相當(dāng)于是塊板。
最后補(bǔ)一張事件分發(fā)圖: