美文网首页
[安卓]RecyclerView的事件拦截机制

[安卓]RecyclerView的事件拦截机制

作者: st0rm23 | 来源:发表于2016-10-14 13:17 被阅读5832次

    动机

    今天st0rm23探究了一下recyclerView的事件拦截机制,我比较好奇,为啥我的拇指按在recyclerView的item上,如果滑动的话是recyclerView来进行响应,而点击的时候是item进行响应。按照之前我看的事件分发的原理来看,应该在DOWN的时候就决定了targetView是item,后面的事件move是怎么给recyclerView的呢?

    拦截机制

    看了源代码发现,其实是有Intercept和cancel机制的。
    MOTION_DOWN:
    父控件recyclerView的dispatchTouchEvent开始,InterceptTouchEvent返回的是false,也就是不拦截。那么流程正常进行,一直dispatch到了itemView,接着itemView响应了MOVE_DOWN的事件,传递链的targetView被设置成了itemView。

    MOTION_MOVE:
    同样是从父控件的recyclerView的dispatchTouchEvent,但是发现这是个MOVE事件检测后InterceptTouchEvent返回的是true。那么好了,要开始拦截了。
    首先是调用dispatchTransformedTouchEvent(ev, cancelChild, target.child, target.pointerIdBits),传给原本的target一个MOTION_CANCEL事件让target将这个CANCEL事件传递下去,这个事件会使得child一下的view的触摸事件全部被取消掉。接着dispatchTouchEvent返回true,层层传递给父亲。
    注意这次的MOTION_MOVE事件并没有使得recyclerView滚动,但是recyclerView的mTargetView被置为了null,也就是传递链的targetView被置为了recyclerView。

    MOTION_MOVE:
    这一次recyclerView真正成为了传递链的targetView,这时候传递到recyclerView的时候,recyclerView就会传递给自己的onTouchEvent,这样就可以正常地执行这个滚动操作了。

    总结:
    也就是在滑动的时候,recyclerView阻截了事件,传递给儿子的是CANCEL事件,同时让自己变成了传递链的末尾,并且消耗了一个motion_move事件。第二个motion_move的时候才会真正开始执行该move的滑动。

    相关文章

      网友评论

          本文标题:[安卓]RecyclerView的事件拦截机制

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