事件
ACTION_DOWN 手指初次接触到屏幕触发
ACTION_MOVE 手指滑动触发,多次触发
ACTION_UP 手指离开屏幕后触发
ACTION_CANCLE 事件被上层拦截时触发
事件流程的主要处理:VIewGroup的分发,View的处理
事件分发的流程
//1.Activity#dispatchTouchEvent()
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
//空方法和屏保有关
onUserInteraction();
}
//下一步Window唯一实现类就是PhoneWindow
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
//2.PhoneWindow.superDispatchTouchEvent()
public boolean superDispatchTouchEvent(MotionEvent event) {
//下一步 mDecor就是DecorView
return mDecor.superDispatchTouchEvent(event);
}
//3.DecorView.superDispatchTouchEvent()
public boolean superDispatchTouchEvent(MotionEvent event) {
//DecorView继承自FrameLayout,FrameLayout继承自ViewGroup,FrameLayout没有重写dispatchTouchEvent(),所以会执行ViewGroup中的dispatchTouchEvent()
return super.dispatchTouchEvent(event);
}
//4.ViewGroup的dispatchTouchEvent()
//5.ViewGroup可能会调用它子view的dispatchTouchEvent()
//6.View会调用自身的onTouchEvent()决定怎么执行
什么叫事件冲突?
事件只有一个,多个人想要处理 ,处理的对象不是我们想给的对象,发生了冲突
最常见的冲突,button的 onTouch和onClick的冲突
先说结论:
onTouch都会回调
若onTouch返回值为true,则onClick不会回调,
若onTouch返回值为false,则onClick会回调
通过源码分析:
View的dispatchEvent中关键代码如下
如上图 li.mOnTouchListener.onTouch(this, event) 就是 与onTouch返回值相关
若返回值为true,则result为true,则下一句 onTouchEvent()则不会执行
进onTouchEvent()源码中看,在MotionEvent.ACTION_UP中,
发现
if (!post(mPerformClick)) {
performClickInternal();
}
进performClickInternal()函数发现调用了performClick(),
performClick()函数中关键代码中发现会执行onClick事件
![
](https://img-blog.csdnimg.cn/20211102080030190.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phdW5jZXh1,size_16,color_FFFFFF,t_70)
所以onTouch的返回值决定着onClick的执行
onTouch返回true时,不会执行onTouchEvent()方法,所以view的onClick不会执行