解决ScrollView与ListView的冲突

我们在使用ScrollView有时会内嵌ListView,但是ListView只能显示一个Item。这是因为ScrollView的重写了measureChildWithMargins方法导致它的子View的高度被强制设置成了MeasureSpec.UNSPECIFIED模式。MeasureSpec.UNSPECIFIED是什么东东呢,我们就介绍一下吧。

MeasureSpec.UNSPECIFIED
不限定,父View不限制子View的具体的大小,所以子View可以按自己需求设置宽高(前面说的ScrollView就给子View设置了这个模式,ListView就会自己确认自己高度)。
MeasureSpec.EXACTLY
父View决定子View的确切大小,子View被限定在给定的边界里,忽略本身想要的大小。
MeasureSpec.AT_MOST
最多的,子View最大可以达到的指定大小(当设置为wrap_content时,模式为AT_MOST, 表示子view的大小最多是多少。)

看列表我们只需将MeasureSpec.UNSPECIFIED,强制改成MeasureSpec.AT_MOST或者MeasureSpec.EXACTLY就好了。知道是什么原因引起,那么接下来就好办了。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(500,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }

现在显示是正确了,但是还是无法监听ListView的滑动事件。这是怎么回事呢,原来呀ScrollView和ListView的滑动冲突了,ScrollView的拦截了滑动事件。
那么我们在如何解决呢?在事件分发中有一个requestDisallowInterceptTouchEvent方法可以在子View中干预父元素的分发过程。代码如下:

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d("list ev action",ev.getAction()+"");
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }
        boolean isIntercept = super.onInterceptTouchEvent(ev);
        Log.d("list isIntercept",isIntercept+"");
        return true;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容