Android事件传递dispatchTouchEvent,ontouch,onInterceptTouchEvent,onTouchEvent,onClick,onLongClick,

看过网上总结过很多帖子,但是发现还不算是很细致,自己最近研究这一部分,分享一下学习心得。

dispatchTouchEvent负责分发事件,源码如下:

if (onFilterTouchEventForSecurity(event)) {
    //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;
    }
}

注意到在dispatchTouchEvent中会观察touchListener是否为空,如果不为空讲执行他的ontouch方法。

1 所以对于ViewGroup,他的执行顺序是:dispatchTouchEvent->onTouch->onInterceptTouchEvent->onTouchEvent。需要注意的是如果在onTouch事件中返回了true,那么将不会再执行onTouchEvent事件。(也不会执行onClick与onLongClick事件,因为这两个事件是写在onTouch事件当中的)

2onInterceptTouchEvent是ViewGroup独有的方法,他的down事件比较特殊,需要注意,如果down事件返回值为true,那么事件不会再传给他的子View,而是到ViewGroup截止了,事件交给ViewGroup的onTouchEvent事件进行处理。并且后续的move,up事件不再走onInterceptTouchEvent,直接交给ViewGroup的ouTouchEVent处理,可以理解为onInterceptTouchEvent有记忆功能。

3再看下onTouchEvent的down,up事件。他们跟onClick与onLongClick有很大的联系,onLongClick事件在down事件后触发,开始计时,当UP事件响应后,会根据持续事件判断,是否触发onLongClick事件,onClick事件在UP事件后触发,并且在onLongClick事件后触发(假如onLongClick返回true,onClick不会执行)。

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        System.out.println("MyButton-----Down");
        return super.onTouchEvent(event);
    }
    if(event.getAction() == MotionEvent.ACTION_UP){
        System.out.println("MyButton-----UP");
        return true;
    }
    return super.onTouchEvent(event);
}

上图,因为down事件交给父类处理,因此会执行onLongClick事件,但是UP中返回true,所以并不会执行onClick。

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        System.out.println("MyButton-----Down");
        return false;
    }
    if(event.getAction() == MotionEvent.ACTION_UP){
        System.out.println("MyButton-----UP");
        return super.onTouchEvent(event);
    }
    return super.onTouchEvent(event);
}

如果将down事件的返回值false,那么up,move事件就不再走onTouchEvent

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        System.out.println("MyButton-----Down");
        return true;
    }
    if(event.getAction() == MotionEvent.ACTION_UP){
        System.out.println("MyButton-----UP");
        return super.onTouchEvent(event);
    }
    return super.onTouchEvent(event);
}

如果将down事件返回值true,那么会执行down与up事件,而onClick不会执行,因为onClick同样要求父类进行处理down与up操作。

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
        System.out.println("MyButton-----Down");
        return super.onTouchEvent(event);
    }
    if(event.getAction() == MotionEvent.ACTION_UP){
        System.out.println("MyButton-----UP");
        return super.onTouchEvent(event);
    }
    return super.onTouchEvent(event);
}
<pre name="code" class="java">这样 down up onclick longclick都会执行
 
 
tv.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        System.out.println("longclick");
        return false;
    }
});
tv.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        System.out.println("onclick");
    }
});
onLongClick如果返回false,那么onClick会执行,如果true,则不会执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值