Android View的onTouchListener、onTouchEvent、onClickListener执行时机

源码分析

我们知道view的事件分发总是从dispatchTouchEvent方法开始,我们就来分析dispatchTouchEvent对应的源码执行逻辑:

 public boolean dispatchTouchEvent(MotionEvent event) {
       ...
        boolean result = false;
        ...
    
        if (onFilterTouchEventForSecurity(event)) {
            if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) 			{
                result = true;
            }
           
            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;
            }
        }

      	...
        return result;
    }

重点分析这段代码:

			 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;
            }

其中ListenerInfo:将View点击事件抽象成class,包含OnClickListener/OnFocusChangeListener/OnScrollChangeListener等等事件;

可以得出如下结论

  • 当View的enable【view使能】为true时,会先执行OnTouchListener.onTouch事件,如果OnTouchListener.onTouch为true,则onTouchEvent事件不会执行,反之会执行onTouchEvent(event)事件

OnClickListener事件在哪里执行的呢?我们看下onTouchEvent(event)方法这段源码:

     switch (action) {
                case MotionEvent.ACTION_UP:
                 			...
                            if (!focusTaken) {
                                // Use a Runnable and post this rather than calling
                                // performClick directly. This lets other visual state
                                // of the view update before click actions start.
                                if (mPerformClick == null) {
                                    mPerformClick = new PerformClick();
                                }
                                if (!post(mPerformClick)) {
                                    performClickInternal();
                                }
                            }
                        }

                    ...
                    break;

其中 performClickInternal()方法如下:
    private boolean performClickInternal() {
        notifyAutofillManagerOnClick();
        return performClick();
    }

 performClick()方法如下:
 public boolean performClick() {
 		...
        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }
        return result;
    }

li.mOnClickListener.onClick(this)正是对应的OnClickListener事件回调。

这一段代码可以得出如下结论:
OnClickListener事件执行的前提是onTouchEvent(event)方法执行了MotionEvent.ACTION_UP事件。

总结

  1. onTouchListener返回false时,执行顺序为 onTouchListener -> onTouchEvent -> onClickListener;
  2. onTouchListener返回true时,只为执行onTouchListener
  3. onClickListener执行的前提是执行了 onTouchEvent且能执行MotionEvent.ACTION_UP事件。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值