Android事件分发机制研究

一直对android的事件分发机制很困惑的,最近又重新看了下这块的知识,配合自己写个小demo,打log研究了下,做个读书笔记,备忘,如有错误,欢迎批评指正。

结论一:如果在父容器中这样写:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}

onInterceptTouchEvent表示是否拦截触摸事件,如果返回true,则其内的子控件的触摸事件,onClick事件都执行不到了。但可通过ViewGroup的requestDisallowInterceptTouchEvent方法干预父控件的事件分发.例如ViewPager来实现左右滑动切换tab,如果tab的某一项中嵌入了水平可滑动的View,比如想滑动tab项中的可水平滑动的控件,却导致tab切换。
你就可以在tab页里面注入viewpager实例,然后在onTouch事件中这么处理。

public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_MOVE:
        pager.requestDisallowInterceptTouchEvent(true);
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
        pager.requestDisallowInterceptTouchEvent(false);
        break;
    }
}

结论二:
如果一个触摸事件传递到一个控件上,它的dispatchTouchEvent会被调用,如果在父控件的onInterceptTouchEvent返回false的前提下,子控件dispatchTouchEvent返回true,代表该子控件自己消费到该触摸事件(onTouchListener会被执行,如果有的话),即触摸事件不会被父控件处理,父控件的onTouchListener和onTouchEvent方法都走不到。

结论三:
触摸事件的分发是从上往下分发的,Activity->Window->View.在View之间也是是从上往下分发的,触摸事件先到达父容器,然后父容器再下发给子View.所以响应触摸事件去执行事情的顺序就反过来了,从子View开始处理起,如果子view的dispatchTouchEvent方法返回了false,则就传递给父容器处理(父容器的onTouchListener会被调到)。注意此时子view的onTouchListener和onTouchEvent(如果onTouchListener返回false)事件依然会被调到,只是调完后给父控件接着调用,如果父容器的dispatchTouchEvent方法也返回了false,则事件继续往上传递,如果dispatchTouchEvent都返回了,false,则Activity的onTouchEvent会被掉到。

结论四:
onTouchListener方法在事件分发过程中的优先级最高,如果一个view设置了onTouchListener方法且返回了true,代表事件已被消费,则他的onTouchEvent方法就走不到了。
注意:我看任大神的书上说如果子View的onTouchEvent方法返回false,则父容器的触摸事件会被调的,而我测下来,不是这样,将子View的onTouchEvent返回了fasle,此时查看子view的dispatchTouchEvent的默认返回值也为false,此时事件确实传到父容器里面调用去了,但如果此时我把子View的diapatchTouchEvent方法强制返回true,(不是默认的返回super.dispatchTouchEvent,而是先是调用super.dispatchTouchEvent,然后返回true),此时即使onTouchEvent返回了false,父控件的触摸和点击事件都没有调到。

所以感觉onTouchEvent返回false父容器的触摸事件会被掉到不准确,应该是dispatchTouchEvent返回false,父容器的触摸事件才会被掉到。不管onTouchEvent返回true or false,只要dispatchTouchEvent返回false,父容器的触摸事件就会被调到。

我的测试demo地址放到github上去了,有需要的可以下载试下,很例子粗糙,仅作测试所用。地址:https://github.com/happycodinggirl/TestTouchEvent
本文文章如有不对的地方,还望指出。

你可能感兴趣的:(Android事件分发机制研究)