«

Android dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent详解

时间:2024-3-2 17:29     作者:韩俊     分类: Android


之前遇到事件分发,去网上找相关文章。。。感觉都没把这几个的关系说明白。研究了几篇不错的文章,今天在这整理一下,希望对大家有所帮助。
首先你要知道一点,当你触摸一个控件的时候,你就会调用该控件(或它的父类)的dispatchTouchEvent方法。那我们就来看一下dispatchTouchEvent方法的源码:

public boolean dispatchTouchEvent(MotionEvent event) {  
    if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&  
            mOnTouchListener.onTouch(this, event)) {  
        return true;  
    }  
    return onTouchEvent(event);  
}  

第一个条件在你setOnTouchListener注册了监听器之后就是true了
第二个条件就是它是不是enable的(在xml布局文件可以设置,button默认为true,imageview为false).关键是第三个条件:

button.setOnTouchListener(new OnTouchListener() {  
    @Override  
    public boolean onTouch(View v, MotionEvent event) {  
       return false; //
       // return true; // 
    }  
}); 

也就是说如果我们在onTouch方法里返回true,就会让这三个条件全部成立,从而整个方法直接返回true。如果我们在onTouch方法里返回false,就会再去执行onTouchEvent(event)方法。(onclick是在onTouchEvent中回调的)

所以总结一下:
首先在dispatchTouchEvent中最先执行的就是onTouch方法,如果ontouch返回true,且该控件是enable的,且已经为其注册了监听器, dispatchTouchEvent也就返回true,那么onTouchEvent就不会执行,onclick也就不会执行了。(返回ture,可以理解为被dispatchTouchEvent它自己消耗了)
如果ontouch返回了false,或者另外两个条件不成立,onTouchEvent就可以执行了,那么dispatchTouchEvent的返回值就得再看onTouchEvent的返回情况了,有点绕(dispatchTouchEvent返回false可以理解为被自己的onTouchEvent消耗了 ,注意在onTouchEvent也是返回true或false,若是true就交给父控件的ontouchenent并且dispatchTouchEvent也会返回true,如果返回false,dispatchTouchEvent也返回false ,会将事件返回给父 View 的 onTouchEvent 进行消费)
其实还有一种情况,那就是返回 系统默认的 super.dispatchTouchEvent(ev),事件会自动的分发给当前 View 的 onInterceptTouchEvent 方法。

那么接下了,我们就来看一下onInterceptTouchEvent 了,这个比较好理解。
这里引用下别人的文章:
onInterceptTouchEvent 的事件拦截逻辑如下:

1 如果 onInterceptTouchEvent 返回 true,则表示将事件进行拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理;
2 如果 onInterceptTouchEvent 返回 false,则表示将事件放行,当前 View 上的事件会被传递到子 View 上,再由子 View 的 dispatchTouchEvent 来开始这个事件的分发(重复上一个逻辑);
3 如果 onInterceptTouchEvent 返回 super.onInterceptTouchEvent(ev),事件默认会被拦截,并将拦截到的事件交由当前 View 的 onTouchEvent 进行处理。(我觉得此处原文不太对,应该是和返回false作用一样吧,将事件继续往下传到子view上,你怎么看,欢迎留言。。。0-0)

下面继续OnTouchEvent:
onTouchEvent用于处理事件,返回值决定当前控件是否消费(consume)了这个事件。尤其对于ACTION_DOWN事件,返回true,表示我想要处理后续事件;返回false,表示不关心此事件,并返回由父类的onTouchEvent(区别于onInterceptTouchEvent ,onTouchEvent是向上传递,直到遇到true才被消费掉)进行处理。

再总结一下:
onInterceptTouchEvent负责对事件进行拦截,拦截成功后交给最先遇到onTouchEvent返回true的那个view进行处理。onInterceptTouchEvent事件的执行顺序是由父控件到子控件,并且优先于自己控件的onTouchEvent方法执行,onTouchEvent事件执行的顺序正好相反由子控件到父控件

参考文章:

http://blog.csdn.net/fangchao3652/article/details/43191159
http://blog.csdn.net/guolin_blog/article/details/9097463#
http://blog.csdn.net/fangchao3652/article/details/43190601
http://blog.csdn.net/guitk/article/details/7057155

标签: android

热门推荐