美文网首页
View事件分发总结

View事件分发总结

作者: wildeyess | 来源:发表于2020-06-30 11:03 被阅读0次

1.事件分发核心方法

  1. dispatchTouchEvent (事件分发,activity,ViewGroup,View 拥有)
  • 返回true表示事件分发成功,事件消费
  • 返回false表示分发事件失败,事件传递到上层View的onTouchEvent
  • 默认调用super.dispatchTouchEvent ,分发事件,执行分发流程,
  1. onInterceptTouchEvent(事件拦截,ViewGroup拥有)
  • 返回true,表示进行拦截,不会进行事件分发到子View,有viewgroup调用自己的onTouchEvent方法进行处理。
  • 返回false,不进行拦截,执行既定的分发过程
  • ViewGroup默认不拦截事件
  1. onTouchEvent(事件消耗,activity,ViewGroup,View 拥有)
  • 执行到该方法说明该View/ViewGroup在触摸返回内
  • 返回true,表示触摸事件被该view消费掉
  • 返回false,表示触摸事件该View没有消费掉,则依次回溯到上层传递的

2. 事件分发流程

  • 分发流程:Activity======>ViewGroup(触摸区域内)====>View(触摸区域内)
  • 消费流程:View(onTouchEvent 返回false)======>ViewGroup(onTouchEvent 返回false)=====>Activity

2.1分发流程结论

  • ACTION_DOWN 事件会一直分发到最底层的View并交由它的onTouchEvent方法处理,返回false,表示它不处理该事件序列,后续的move,up,等事件将不会向他分发。同理与这个事件序列的所有View,当所有View都没有消费这个事件则最后调用activity的onTouchEvent方法,后续的move,up事件直接由activity的 dispatchTouchEvent (activity) ======>onTouchEvent(activ)
  • 事件拦截onInterceptTouchEvent,可以拦截所有事件,也可以拦截部分事件,down-move-up,子View可以调用父View的requestDisallowInterceptTouchEvent,不允许父View拦截,但如果父View拦截了Down事件,这个方法是无效的。
  • view什么时候会消耗事件,即onTouchEvent返回true,clickAble或longclickable有一个为真,具体表示就是添加相关的监听事件,表示我们有相关业务需要处理。mOnTouchListener的ontouch事件要优先于onTouchEvent事件,当返回true时,表示事件已经被消费,不会再进行分发。
    view的dispatchTouchEvent 部分源码
//noinspection SimplifiableIfStatement
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }

            if (!result && onTouchEvent(event)) {
                result = true;
            }

setOnTouchListener

   /**
     * Register a callback to be invoked when a touch event is sent to this view.
     * @param l the touch listener to attach to this view
     */
    public void setOnTouchListener(OnTouchListener l) {
        getListenerInfo().mOnTouchListener = l;
    }

setOnClickListener

    /**
     * Register a callback to be invoked when this view is clicked. If this view is not
     * clickable, it becomes clickable.
     *
     * @param l The callback that will run
     *
     * @see #setClickable(boolean)
     */
    public void setOnClickListener(@Nullable OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }

setOnLongClickListener

/**
     * Register a callback to be invoked when this view is clicked and held. If this view is not
     * long clickable, it becomes long clickable.
     *
     * @param l The callback that will run
     *
     * @see #setLongClickable(boolean)
     */
    public void setOnLongClickListener(@Nullable OnLongClickListener l) {
        if (!isLongClickable()) {
            setLongClickable(true);
        }
        getListenerInfo().mOnLongClickListener = l;
    }

3.事件序列

一个事件序列包含ACTION_DOWN(1次) -> ACTION_MOVE(N次) -> ACTION_UP(1次),事件分发包含一个完整的事件序列(从屏幕的的触摸到离开的过程)。


view事件分发规则说明图

相关文章

网友评论

      本文标题:View事件分发总结

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