参考链接:Android事件分发机制详解:史上最全面、最易懂_安卓事件分发流程-优快云博客
Android事件分发机制详解:史上最全面、最易懂_android 事件分发-优快云博客
1、安卓事件有:
当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件(Touch事件)。
- MotionEvent.ACTION_DOWN:按下View(所有事件的开始)
- MotionEvent.ACTION_MOVE:滑动View
- MotionEvent.ACTION_CANCEL:非人为原因结束本次事件
- MotionEvent.ACTION_UP:抬起View(与DOWN对应)
2、事件分发本质:
将点击事件(MotionEvent)向某个View进行传递并最终得到处理
3、事件在哪些对象之间进行传递?
一个点击事件产生后,传递顺序是:Activity(Window) -> ViewGroup -> View
4、总结:Android事件分发机制的本质是要解决:点击事件由哪个对象发出,经过哪些对象,最终达到哪个对象并最终得到处理。
5、一般的事件传递场景有:
- 默认情况(一层一层往下传)
- 处理事件
- 拦截DOWN事件
- 拦截后续事件(MOVE、UP)
6、Activity事件分发机制
当一个点击事件发生时,调用顺序如下
- 事件最先传到Activity的dispatchTouchEvent()进行事件分发
- 调用Window类实现类PhoneWindow的superDispatchTouchEvent()
- 调用DecorView的superDispatchTouchEvent()
- 最终调用DecorView父类的dispatchTouchEvent(),即ViewGroup的dispatchTouchEvent()
- 当一个点击事件发生时,事件最先传到Activity的dispatchTouchEvent()进行事件分发,最终是调用了ViewGroup的dispatchTouchEvent()方法
如果ViewGroup的dispatchTouchEvent()返回true就不执行Activity的onTouchEvent()方法;如果返回false,就执行。
- 这样事件就从 Activity 传递到了 ViewGroup
7、ViewGroup事件分发机制
- Android事件分发是先传递到ViewGroup,再由ViewGroup传递到View
- 在ViewGroup中通过onInterceptTouchEvent()对事件传递进行拦截
- onInterceptTouchEvent方法返回true代表拦截事件,即不允许事件继续向子View传递;
- 返回false代表不拦截事件,即允许事件继续向子View传递;(默认返回false)
- 子View中如果将传递的事件消费掉,ViewGroup中将无法接收到任何事件。
8、View事件分发机制
- onTouch()的执行高于onClick()
- 每当控件被点击时:
- 如果在回调onTouch()里返回false,就会让dispatchTouchEvent方法返回false,那么就会执行onTouchEvent();如果回调了setOnClickListener()来给控件注册点击事件的话,最后会在performClick()方法里回调onClick()。
onTouch()返回false(该事件没被onTouch()消费掉) = dispatchTouchEvent()返回false(继续向下传递) = 执行onTouchEvent() = 执行OnClick()
- 如果在回调onTouch()里返回true,就会让dispatchTouchEvent方法返回true,那么将不会执行onTouchEvent(),即onClick()也不会执行;
onTouch()返回true(该事件被onTouch()消费掉) = dispatchTouchEvent()返回true(不会再继续向下传递) = 不会执行onTouchEvent() = 不会执行OnClick()
- 如果在回调onTouch()里返回false,就会让dispatchTouchEvent方法返回false,那么就会执行onTouchEvent();如果回调了setOnClickListener()来给控件注册点击事件的话,最后会在performClick()方法里回调onClick()。