ScrollView嵌套ListView(ViewGroup事件分发)

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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值