ScrollView嵌套ListView(ViewGroup事件分发)

来源:互联网 发布:python数据分析 视频 编辑:程序博客网 时间:2024/05/22 03:10

ScrollView嵌套ListView事件分发问题(深藏不露的disallowIntercept

#转载请注明出处,谢谢!
前几天朋友问起ScrollView嵌套ListView,滑动事件只作用于ScrollView,ListView内部无法滑动的问题,他虽然找到了解决办法,但是对其原因还是云里雾里,知其然,不知其所以然。在这里我就带着想知其所以然的朋友们,来探寻下如何解决这类事件分发的问题,我的博客还是以思路为准(这里提供两种解决方案),会稍微解读下源码,首先上图:
问题解决前,滑动ListView,内部item没有动静,倒是整个ScrollView滚动动起来了,自然不是我们想要的。

问题解决后,滑动listView,内部item上下滚动,滑动listView以外的部分,整个ScrollView滚动,完美。

从现象上来看,明显是listView的move事件被ScrollView截获了,其实有经验的朋友应该会发现,一般事件分发的冲突事件都是针对move的,很少会有需要解决点击冲突事件的吧(如果有,说明你还是个菜鸟偷笑,开个玩笑!)。想到截获,我们是不是心里有了主意,对,重写"onInterceptTouchEvent"方法,返回false,让ScrollView无法截获事件,这样问题是不是就解决了,那么第一种解决方案出来了:

方案一、重写onInterceptTouchEvent方法:

@Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        return false;    }
那么大家可能会问,为啥down事件不截获,move事件就给截获了呢?!这个就是领导和下属的区别,你想啊,做事情肯定是交给下面的人做啊(所以有了事件分发,大部分事都交给下属的下属……干了),如果要下班了,你说是不是领导得第一个走,好一点的领导可能自己走了,还会告诉下面的人也可以下班了(这就是第一种解决方案,遇到好领导,他重写了onInterceptTouchEvent,默认不拦截,所有消息共享)坏领导肯定想让你多加班,多给他带来收益啊,于是就自己走了也不说让你走,继续加班呗!!!现在我们来看一下“dispatchTouchEvent”源码:

从源码上来看,第二种解决方案应该是从disallowIntercept入手了,这个变量从字面意思来看是“不允许拦截”,这个可以有啊,那么是不是有可以设置不允许拦截的方法呢,还真有"requestDisallowInterceptTouchEvent(true)"。希望来了,领导让我们加班,不让我们move,我们是不是可以申请不加班。那么在哪里申请呢,down的时候你不用操心,领导绝对不会拦截,生怕你不干,自然是在move的时候了,这个时候就有了第二种解决方案:

方案二、申请不被拦截:(也可以在listView的onTouch事件中申请,这样就不需要自定义ScrollView了,设置对象是ScrollView)

 @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        //禁止拦截触摸事件(允许往下传递)//requestDisallowInterceptTouchEvent(true);        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                break;            case MotionEvent.ACTION_MOVE:                //禁止拦截触摸事件(允许往下传递)requestDisallowInterceptTouchEvent(true);                break;            case MotionEvent.ACTION_UP:                Log.e("up", "dispatch "+ sum);            case MotionEvent.ACTION_CANCEL:                //释放-禁止拦截触摸事件requestDisallowInterceptTouchEvent(false);                break;            default:                break;        }        return super.dispatchTouchEvent(ev);    }
最后给大家一张事件分发流程图,方便大家更好的理解和吸收:


这是根据源码绘制的流程图,Event进来有两大关卡可以拦截,第一道关卡是disallowIntercept,第二道是onIntercept,只要设置其中任何一个都可以让下面的view顺利得到想要的Event,讲到这里基本就告一段落了,欢迎大家访问我的其他博客!!!
源码较简单,不建议下载,当然也提供下载,这里只提供CSDN的下载:http://download.csdn.net/detail/aiyh0202/9659839
1 0
原创粉丝点击