Android事件分发

事件传递的过程分析

  • 事件传递 从最外层父View将事件 传递到 内部View 首先传递前 判断自己的_dispatchTouchEvent_ 方法是否支持分发,支持分发的话,会传递自己View的_onInterceptTouchEvent_ 方法,看自己是否进行拦截处理,若拦截则会传递到自己的_onTouchEvent_,若不拦截会传递到子View的_dispatchTouchEvent_ 方法进行处理,内部处理流程和上一层View的处理流程一样: dispatchTouchEvent–>onInterceptTouchEvent–>onTouchEvent

DispatchTouchEvent之return

  • false: 返回给父View的OnTouchEvent事件

  • true :停止传递分发、事件不传递、也就是不会有onTouchEvnet事件之说,因为onTouchEvent事件,执行的时候是事件全部传到最底部View后才会执行,最底部的onTouchEvent不消费的话,才会向上一级的父View的onTouchEvent传递(也就是才会执行到父View的该方法、、当然除非是中间拦截了,才会不向下传递、直接执行自己的OnTouchEvent方法)

  • super.DispatchTouchEvent之return:支持分发(也就是该事件已经产生、会进行处理、直到有人将其消费、如果返回上边的,该事件就相当于没有产生,直接返给窗体View、直接被扼杀在摇篮里)、会传递到该View的onInterceptTouchEvent方法,由该方法来处理看是否继续向下传递;

onInterceptTouchEvent之return

  • false: 不拦截传递给下一层子View进行事件分发方法:dispatchTouchEvent() 流程相同继续走。
  • true: 拦截事件,不向下传递事件,会传递给自己的onTouchEvent()事件处理响应。
  • super.onInterceptTouchEvent(): 等同于true,即进行拦截,交由自己的onTouchEvnent进行处理

onTouchEvent()之return

  • false: 不消费、传递到上一层的View的onTouchEvnet?

  • true : 消费,自己执行onTouchEvnet方法

  • super.onTouchEvnet(): 等同于false 传递到上一层父View的 onTouchEvent进行处理

       event.getPointerCount()//判断手指
       MotionEvent.ACTION_XXX
       MotionEvent.ACTION_UP//需要全部手指全部离开屏幕才会调用
       MotionEvent.ACTION_POINTER_UP//当存在多个手指触碰时,抬起一指就会执行该方法
       MotionEvent.ACTION_POINTER_DOWN
    

GestureDetector 手势管理之OnGestureListener

  • void onShowPress(MotionEvent e);

  • boolean onSingleTapUp(MotionEvent e);

  • void onLongPress(MotionEvent e);

  • boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);

接收方式

  • onTouchEvent 内部调用—mGestureDetector.onTouchEvent(event);

子View控制父View拦截

getParent().requestDisallowInterceptTouchEvent(true);

  • true:表示父View对事件进行拦截无效例如:onInterceptTouchEvent内部对事件down、move返回true,也是不起作用的

  • false:表示父View对内部子View的拦截是有效的

总结

  • 所有的事件都是先往最底层传递的、最底层没有消费时才会一层一层的往外层传到各自的onTouchEvent()方法中,但是事件首先都是会执行DispatchTouchEvent方法进行分发传递到下一层的,其中会走每一层的:DispatchTouchEvent和onInterceptTouchEvent方法判断是不是需要拦截,不拦截就继续往下一层走,所以onInterceptTouchEvent的Down事件是都会走的,:包括MOVE事件、UP事件,当最外层的事件把Down拦截了,下边的就不会走了,当没有拦截,会一层一层走,,当最底层有方法表示

    getParent().requestDisallowInterceptTouchEvent(true);
    谁都不能拦截我的事件,那么事件就不会往上在传递到外层的move、up等事件了就会到该处消费结束!!!也就是说这个时候onInterceptTouchEvent的MOVE事件和UP事件都不会走了(对应的方法都不走了),其他情况还是每一层新的事件都会进行传递所以会出现那种:不拦截Down事件拦截Move事件的情况,,所以如果底部有拦截但是外层也想获取点击的坐标位置:就可以在onInterceptTouchEvent方法的down事件中进行获取点击的坐标位置、

Android事件分发