参考:https://blog.csdn.net/carson_ho/article/details/54136311#commentsedit ORZ拜读跪谢
1.1Touch事件的相关细节(发生触摸的位置、时间等)被封装成MotionEvent对象,当一个点击事件(MotionEvent )产生后,系统需把这个事件传递给一个具体的 View 去处理。
事件类型 具体动作
MotionEvent.ACTION_DOWN 按下View(所有事件的开始)
MotionEvent.ACTION_UP 抬起View(与DOWN对应)
MotionEvent.ACTION_MOVE 滑动View
MotionEvent.ACTION_CANCEL 结束事件(非人为原因)
1.2事件分发的机制本质是将点击事件MotionEvent传递到某个具体的View以及处理的整个过程
1.3 事件在Activity、ViewGroup、View对象之间进行传递
1.4事件传递的顺序:Activity -> ViewGroup -> View`
1.5 事件分发过程由哪些方法协作完成?
dispatchTouchEvent() 分发传递点击事件 当点击事件能够传递给当前View时会被调用。
onInterceptTouchEvent() 判断是否拦截了某个事件 注意该方法只存在于ViewGroup 普通的view中没有该方法 在dispatchTouchEvent()内部调用
onTouchEvent() 处理点击事件 在dispatchTouchEvent()内部调用
------------------------------------------------------------------------------传递流程---------------------------------------------------------------------------------一:activity中的传递
点击屏幕,Activity的调用dispatchTouchEvent分发方法执行,该方法源码内实际有调用ViewGroup的dispatchTouchEvent分发方法。
此处实现了activity到viewGroup的传递。
如果ViewGroup的dispatchTouchEvent 返回true则事件不在传递,自己消费掉 即事件传递结束
如果ViewGroup的dispatchTouchEvent 返回false则事件传递,执行Activity.onTouchEvent() 无论该方法返回什么 都是结束事件传递。
上述 「源码内实际有调用ViewGroup的dispatchTouchEvent分发方法」实现了activity到viewGroup的传递
二:viewGroup中的传递
ViewGroup的dispatchTouchEvent分发方法中 源码内实际调用ViewGroup.onInterceptTouchEvent拦截方法
如果ViewGroup的onInterceptTouchEvent返回true则表示拦截,不想子view传递点击事件,自己消费掉,调用自身的
onTouch()--->onTouchEvent()--->performClick()--->onClick() 即事件传递结束.
情景:自己重写拦截方法让它返回true或者没有view去接受该点击事件时。
如果ViewGroup的onInterceptTouchEvent返回false则事件传递,允许传递给子view,也就是for循环遍历子view中被点击的那个view,
如果没有相应子view(例如点击空白处) 则和返回true一样自己消费掉,不传递。
找到被电击的那个子view后执行子view的dispatchTouchEvent()分发事件方法,实现了GroupView到子view的传递。
三:view中的传递
在view的dispatchTouchEvent()分发方法中源码中有调用view的onTouch()方法(这也是onTouch方法优先于onTouchEvent()方法和onClick()方法的原因)
button.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false; //则继续执行button的onClick()
//return true;//则结束传递
}
});
onTouch()方法可以重写定义。
onTouch方法若返回true则事件结束传递。
onTouch方法若返回false则会调用view的onTouchEvent()方法。
在onTouchEvent()中的抬起UP分支中
执行view的performClick方法--->view的onClick()方法返回true 结束传递。
至此到在子view的传递已经结束。