当前位置:   article > 正文

《Android 开发艺术探索》笔记4--View事件分发与滑动冲突_android view的ontouchlistener和子view的点击事件冲突

android view的ontouchlistener和子view的点击事件冲突

思维导图

View事件分发与滑动冲突.png

View事件分发机制

点击事件传递规则

所谓点击事件的事件分发,就是对MotionEvent事件的分发过程,传递给某一个View.

在事件传递中有三个方法是贯穿始终的

  • dispatchTouchEvent():进行事件的分发 如果事件能传递到View那么此方法一定会被调用,返回值受当前View的onTouchEvent()和下级View的dispatchTouchEvent()的影响. 表示是否消耗当前事件.
  • onInterceptTouchEvent(): 判断是否拦截事件,如果当前View拦截了某个事件,那么在同一个事件序列中, 此方法不会被再次调用, 返回结果表示是否拦截当前事件.
  • onTouchEvent(): 在dispatchTouchEvent中被调用. 用来处理点击事件, 返回结果表示是否消耗当前事件,如果不消耗, 则在同一个事件序列中, 当前View无法再次接收到事件.

如果把源码中的各种判断去掉, 只留最核心的代码, 那么就如下:

public boolean dispatchTouchEvent(MotionEvent event) {

   boolean consume = false;   //表示这个事件最终的处理结果

   if (onInterceptTouchEvent(event)){

        //事件被拦截自己处理

       consume = onTouchEvent(event);

   }else{

        //事件被分发到子view的dispatchTouchEvent()中

       consume = child.dispatchTouchEvent(event);

   }

   return consume;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

OnTouchListener() , onTouchEvent() , OnClickListener() 的优先级

上面说了普遍情况下的事件分发. 如果这个View同时还添加了OnTouchListenerOnClickListener. 此时的优先级如下:

OnTouchListener –> onTouchEvent –> OnClickListener

onTouchEvent()能否被最终调用取决于设置了OnTouchListener()中的onTouch()的返回值, 如果onTouch()返回的结果是false,那么onTouchEvent()会被调用. 如果返回true那么onTouchEvent()不会被调用.

而最后被调用的OnClickListener()方法是在onTouchEvent()被调用的. 所以如果onTouchEvent()方法如果执行, 那么对应的添加的onClickLisener()才会被调用. 所以如果在OnTouchListener()中的onTouch()返回true那么onTouchEvent()不会被调用,内部调用OnClickListener也就更无法被调用.

一个事件的传递过程遵循如下

Activity -> Window ->decor view->ViewGroup-> View

如果事件一直不拦截,传递到了最里层的View而最里层的View的onTouchEvent()也返回false不消费, 那么事件就会向上级的onTouchEvent()传递,如果还返回false就依次传递.

对于事件机制的规则:

  1. 事件序列是指按下到抬起之间发生的一系列
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/852197
推荐阅读
相关标签
  

闽ICP备14008679号