android motionevent事件分发 复习

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

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值