Android事件的传递机制
前言
最近面试了很多公司,大多数公司都问到了这么一个问题,就是Android事件的传递机制,那Android事件的传递机制到底是怎么一回事?今天我们来探讨探讨!
正文
Android中三个方法是关于事件传递的,分别是dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent,那这三个方法分别有什么用呢?其实我们可以从字面上的意思可以理解分别是分配触摸事件、截断触摸事件以及响应触摸事件,那这三个方法到底在事件的传递机制中扮演着什么角色?我们一起可以来看看源码!在看源码前,我们先明确事件的基本传递顺序和哪些类中有哪些触摸事件的方法!(后面会具体证明)传递顺序是从最外层传递到最里层,例如:Activity - - > LinearLayout - - > TextView,下面是哪些类中有哪些事件方法
类 | 相关子类 | 方法 |
---|---|---|
Activity类 | Activity…… | dispatchTouchEvent(); onTouchEvent(); |
View容器(ViewGroup的子类) | FrameLayout、LinearLayout、ListView、ScrollVIew…… | dispatchTouchEvent(); onInterceptTouchEvent(); onTouchEvent(); |
View控件(非ViewGroup子类) | Button、TextView、EditText…… | dispatchTouchEvent(); onTouchEvent(); |
其中onInterceptTouchEvent只有ViewGroup有,为什么ViewGroup才有onInterceptTouchEvent方法,因为他是截断事件,而截断事件不可能存在Activity中与View中,在Activity中,那你截取触摸事件干什么呢?在Activity中将事件截取了,那Activity中的布局控件就获取不到触摸事件,那相当于没有布局上控件的什么事!所以Activity中Google官方没有给Activity设置onInterceptTouchEvent方法,那View中为什么没有该方法呢?那是因为View本来就是最底层了,View没有下一层的子控件了,不需要向下传递事件,你截取事件与不截取事件都是一样的,所以也没有onInterceptTouchEvent的方法!
下面我们重写三个类,分别是FrameLayout、LinearLayout、TextView
FrameLayout
public class MyFrameLayout extends FrameLayout{
public MyFrameLayout(@NonNull Context context) {
super(context);
}
public MyFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Logger.e("Leezp", "MyFrameLayout调用dispatchTouchEvent分配任务");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Logger.e("Leezp", "MyFrameLayout调用onInterceptTouchEvent是否阻止任务?");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Logg