Android输入事件的源头是位于/dev/input/下的设备节点,而输入事件的终点是由WMS管理的某个窗口,最终由窗口中的View处理。最初的输入事件为内核生成的原始事件, 而交付给窗口的分为KeyEvent(键盘)或MotionEvent(鼠标和触摸屏)两种对象。输入事件由Native层进入到Java层的第一个函数是InputEventReceiver.dispatchInputEvent(),
https://mp.csdn.net/console/editor/html/107266043
java层从ViewRootImpl开始分析,viewrootimpl中
紧接着:
viewrootimpl持有的mview就是DecorView,decorview的parentview就是viewrootimpl。
而Decorview,继承的viewgroup,也就是framwlayout,但是Decorview和viewgroup都没有重写这个dispatchPointerEvent,因此调用的是:
dispatchTouchEvent走的则是decorView重写的:
callback就是activity在onattach是注册进去的,也就是activity:
而getwindow就是phonewindow,
于是走回了decorview的superDispatchTouchEvent,而decorview的superDispatchTouchEvent:
decorview是继承view的,于是走到了viewgroup的dispatchtouchevent
https://mp.csdn.net/console/editor/html/107266043
然后开始view的事件分发:
viewgroup
1.
requestDisallowInterceptTouchEvent 设置mGroupFlags&FLAG_DISALLOW_INTERCEPT的值
2.
private TouchTarget mFirstTouchTarget;
dispatchTouchEvent{
if(action_down){
清除mGroupFlags状态
}
if(action_down || mFirstTouchTarget == null){
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
}
}
if(! intercepted && actionMasked == MotionEvent.ACTION_DOWN){
for (int i = childrenCount - 1; i >= 0; i--) {
if( child.dispatchTouchEvent(event)){
mFirstTouchTarget = TouchTarget.obtain(child);
break
}
}
if(mFirstTouchTarget != null){//说明已经有响应的view了
handled = mFirstTouchTarget.child.dispatchTouchEvent;
}else{
handled = super.dispatchTouchEvent;
}
if(actionMasked == MotionEvent.ACTION_UP){
mFirstTouchTarget = null;
}
return handle;
}
view :
boolean dispatchTouchEvent{
if(mOnTouchListener.onTouch)
return true;
}
if( onTouchEvent(event)){
return true
}
return false;
}
boolean onTouchEvent{
if (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}
if(mOnClickListener.onClick){
return true;
}
if(clickable){
return true
}
return false
}
https://mp.csdn.net/console/editor/html/107266043
https://mp.csdn.net/console/editor/html/107266043
与事件分发过程相关的几个方法主要有:
(1)dispatchTouchEvent:用来进行事件分发,如果事件能够传递给当前View,那么次方法一定会被调用,返回值受当前View的onTouchEvent和下级View的dispatchTouchEvent方法影响;
(2)onInterceptTouchEvent:在dispatchTouchEvent方法内部调用,用来判断是否拦截某个事件,如果当前VIew拦截了某个事件,那么在同一事件序列中,此方法不会再被调用,返回结果表示是否拦截当前事件;
(3)onTouchListener :在dispatchTouchEvent方法中调用,其调用优先级高于onTouchEvent,返回true,则不再走onTouchEvent;
(4)onTouchEvent:在dispatchTouchEvent方法中调用,用来处理点击事件,反馈结果表示是否消耗当前事件,如果不消耗,则在同一事件序列中,当前View无法再次接受事件;
(5)setPressed,在onTouchEvent中,优先级高,之后才执行TouchDelegate
(6)TouchDelegate的onTouchEvent,在onTouchEvent中,如果mTouchDelegate的onTouchEvent返回true,则直接返回。
(7)onclickListener:在onTouchEvent中,在发生点击事件时,会调用该方法,表示有点击事件;onclick发生的前提是当前View可以点击,并且它收到down和up事件;
(8)onLongClickListener:当长按事件发生时会回调该方法,手指或鼠标按下500ms之后就会发生长按事件,如果onLongClick返回true,就 不会在调用onClick方法,返回false,就会调用onClick
如果一致返回false,最后回走回activity的dispatchTouchEvent,执行activity的onTouchEvent