美文网首页
[安卓]Android事件分发

[安卓]Android事件分发

作者: st0rm23 | 来源:发表于2016-09-19 14:05 被阅读88次

    1. View的事件分发小结参考CSDN

    • dispatchTouchEvent
    • 每一次触摸会触发View的dispatchTouchEvent事件,若非enable跳过
    • 检测touchlistener,如果enable调用(有可能被true阻截后续onTouchEvent)。
    • 否则return onTouchEvent(event),返回值如果是false,那么下一次action就不分发了。
    • onTouchEvent
    • 如果不是enable的,那么return clickable || longClickable
    • 如果有TouchDelegate,那么调用TouchDelegate.onTouchEvent(有可能被true阻截后续switch)
    • 如果是clickable || longClickable,那么switch做动作
      • ACTION_DOWN, 带上prepressed标签,开始计算按下延时
      • ACTION_MOVE, 检测是不是move到view外面了,如果是停止相应pressed状态,否则啥都不干
      • ACTION_CANCEL, 停止相应press状态
      • ACTION_UP, 该次触摸结束,触发focus或者click或者longclick
    • 如果不是clickable,不是long clickable,不是enable,那么return false,终结返回。

    2. ViewGroup的事件分发小结参考CSDN

    • dispatchTouchEvent (非直接继承view)
    • ACTION_DOWN, 重置targetView,使用onInterceptTouchEvent判断是否拦截
      • 如果不拦截的话,先序遍历child,找在点击范围内的child,递归调用child.dispatchTouchEvent(),如果返回true表示找到了targetView,return true打断后续。
      • 如果拦截的话,后续当没有targetView处理。
    • 没有targetView,把自己当做view来当做点击自己super.dispatchTouchEvent(ev)
    • 有targetView,再看一下自己拦不拦截motionEvent,不拦截直接调用target.dispatchTouchEvent()
    • onInerceptTouchEvent
      • 如果返回true,自己被当成了一个view(viewGroup性质终结)。那么这里收不到后续的events了,直接被投递到自己的onTouchEvent,原有的target view都会收到同样的events,但是action是cancel。
      • 如果返回false,自己被当成了一个viewGroup,后续的event都会经过这再被传递到target view。

    3. 总结

    • step 1 屏幕接受到触摸事件,是从root控件的dispatchTouchEvent开始的。

    • step 1.5 如果控件是viewGroup,那么判断调用onInerceptTouchEvent是否拦截

      • 如果拦截,那么把自己当成一个view来处理,进入step 2。
      • 否则递归调用点击范围内的子控件dispatchTouchEvent,相当于在step1-1.5之间递归循环,直到碰到一个"普通的view"或者一个"表示拦截的viewGroup"。
    • step 2 总有一个控件以view的身份来接受这个事件,那么开始检测是否有touchListener,如果有调用它。

    • step 3 最终调用onTouchEvent

    • 注意:事件分发中有一个target view概念,如果在ACTION_DOWN的过程中递归确定下来了要消费的那个view,那么UP/MOVE事件都不会再递归了,直接就找到那个view了。

    相关文章

      网友评论

          本文标题:[安卓]Android事件分发

          本文链接:https://www.haomeiwen.com/subject/fkngettx.html