OnClick不被调用,onTouchEvent不被调用的情况是onTouch的DOWN返回true

(1)首先没有设置OnClickListener的情况下,onTouch的返回值表示的就是View对点击事件是否消耗,如果在DOWN事件传递过来时返回false,那么剩下的MOVE直到UP的事件都不会被onTouch接收到;如果在DOWN事件返回true,那么剩下的直到UP的事件都会接受到,无论你之后的返回值。 
(2)在同时设置了OnTouchListener与OnClickListener之后,情况就有些复杂了: 
情况1:如果onTouch在DOWN时返回了true,那么onTouch就和(1)一样收到剩下的所有事件,但onClick就不会被执行; 
情况2:如果onTouch在DOWN时返回了false,与(1)不同的是,onTouch尽管在DOWN时返回了false,但之后的所有事件仍能接受到,并且onClick会在之后被调用。

3、原因解析 
首先解析这个问题其实很简单,就是一个View的关键函数dispatchTouchEvent,让我们直接来看代码:

public boolean dispatchTouchEvent(MotionEvent event){  
    ... ...  
    if(onFilterTouchEventForSecurity(event)){  
        ListenerInfo li = mListenerInfo;  
        if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED  
            && li.mOnTouchListener.onTouch(this, event)) {  //(1)onTouch调用
            return true;  
        }  
        if(onTouchEvent(event)){  //(2)onTouchEvent调用
            return true;  
        }  
    }  
    ... ...  
    return false;  
}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

dispatchTouchEvent就是触摸时间分发的关键函数,相信看过相关解析的一定对这个很清楚,如果一个事件能够传递给当前View,那么一定会调用这个方法,返回值就是表示是否消耗此事件,那么我们来根据上面的规律进行分析: 
(1)如果没有设置OnClickListener,只设置了OnTouchListener,那么在代码(1)处就会调用onTouch,如果DOWN事件时返回了true,那么剩下的事件都会交由此View进行处理;如果返回了false,那么就会执行代码(2)处的onTouchEvent函数,如果设置了OnClickListener,就会在其中进行调用,如果没有设置,dispatchTouchEvent就会返回false,那么剩下的事件都不会交由此View进行处理; 
(2)如果同时设置了OnTouchListener与OnClickListener,那么我们再按上面的两种情况进行分析: 
情况1:onTouch在DOWN时返回了true,那么代码(1)处就得到了真的结果,直接就返回了true,可以知道后面代码(2)处的onTouchEvent函数不会被执行,那么自然你的OnClickListener就不起作用了,onClick就不会被执行; 
情况2:onTouch在DOWN时返回了false,那么代码(1)处就不会得到真的结果,后面代码(2)处的onTouchEvent函数就会得到执行,而如果你设置了OnClickListener,View就会处于CLICKABLE状态,那么onTouchEvent函数就会返回true,dispatchTouchEvent就会返回true,那么这时后面的事件由于DOWN时返回true,就会统统交由此View进行处理,自然你的onTouch中也能够监听到后面的所有事件!这样上面的情况就能够得到解释了。

4、总结 
这样我们就搞清楚了onTouch与onClick两种监听的相互关系,总的来说onTouch优先级更高,如果onTouch在DOWN中返回true,那么onClick就不会执行;但如果onClick被设置,那么一定程度上也会影响onTouch。关于具体的触摸事件传递机制我之后会配合设计模式写一个全面的博文,加强自己的认识和理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值