一、基础
1.事件在哪里传递?
Activity
\
ViewGroup
\
View
2.事件
而在触摸发生的时候就会将事件封装成 MotionEvent 对象。
MotionEvent.ACTION_DOWN:按下View.
MotionEvent.ACTION_UP:抬起View.
MotionEvent.ACTION_MOVEi:滑动View.
MotionEvent.ACTION_CANCEL:结束事件,非人为.
3.接触的方法
dispatchTouchEvent():事件分发.
onInterceptTouchEvent():事件拦截,只存在ViewGroup.
onTouchEvent():事件处理.
一般情况下,给父类调用则会继续分发,返回true则消费,返回false则不处理。
二、Activity事件分发
当点击事件发生的时候,首先事做一个应用的界面上发生的,也就是Activitypublic boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// 空方法
onUserInteraction();
}
// 获取PhoneWindow类调用superDispatchTouchEvent()方法
// 其中实现了mDecor.superDispatchTouchEvent(event)
// 在mDecor中则调用其本身的dispatchTouchEvent(event)。这里的DecorView是PhoneWindow内部类,顶层集成ViewGroup
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
// 没有控件接收则调用这里
return onTouchEvent(ev);
}
...
// 没有控件接收则调用这里
public boolean onTouchEvent(MotionEvent event) {
// <font color=#C7254E>处理触摸事件是否在Window边界外</font>
if (mWindow.shouldCloseOnTouch(this, event)) {
finish();
return true;
}
return false;
}
Activity<dispatchTouchEvent>
-> 跳转至Window(PhoneWindow)<superDispatchTouchEvent>
-> 跳转至DecorView(ViewGroup)<superDispatchTouchEvent>
-> 跳转至ViewGroup<dispatchTouchEvent>
这里注意分发的时候所调用的类、实现类和方法名称。
三、ViewGroup事件分发
|
在这里来分发触摸事件,
true:消费当前事件,并不调用onTouchEvent()方法
false:不消费当前事件,返回至父控件
默认:事件分发
|
在ViewGroup中可以通过OnInterceptTouchEvent()来判定是否需要拦截触摸事件,此时会对其子控件通知CANCEL通知
true:拦截当前事件,但是会调用onTouchEvent()方法
false:不拦截,默认
|
此方法会在调用处理点击事件时调用,是在完成自己对点击消费时对应对方法。
true:消费点击事件,不向上传递
false:默认,向上传递
四、View
可以看到View中也有以上几个方法对调用(没有onInterceptTouchEvent方法),过程类似。
在onTouchEvent中:
true:消费当前事件,不调用onClick(),并且不会想上传递
false:不消费当前事件,并且会向父控件传递,并且调用onClick()方法