美文网首页
解决ScrollView与ListView的冲突

解决ScrollView与ListView的冲突

作者: 朩浀樹佺 | 来源:发表于2017-02-27 16:35 被阅读44次

    我们在使用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;
        }
    

    相关文章

      网友评论

          本文标题:解决ScrollView与ListView的冲突

          本文链接:https://www.haomeiwen.com/subject/yfizwttx.html