ScrollView嵌套ListView的问题

如果ScrollView嵌套ListView后,ListView只会显示一个item的高度,如下图:


图1.png

原因是ScrollView在测量的时候改变了子view(即ListVIew)的测量模式,贴代码:

//scrollview的onmeasure()方法
if (child.getMeasuredHeight() < desiredHeight) {
                final int childWidthMeasureSpec = getChildMeasureSpec(
                        widthMeasureSpec, widthPadding, lp.width);
                final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        desiredHeight, MeasureSpec.EXACTLY);
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
            }

整个测量过程也是一次根节点开始的遍历过程,测量过程中父布局需要告诉子布局具体的模式和宽高值,对子布局来说是一种约束,子布局需要在规定的范围内进行绘制。
因此也就是scrollview改变了listview的测量模式和值(log得出Listview使用的是UNSPECIFIED模式),所以Listview最终只显示一个item的高度。

解决方法:
重写ListView的onmeasure()方法:

   @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        int mode = MeasureSpec.getMode(heightMeasureSpec);
//        switch (mode) {
//            case MeasureSpec.UNSPECIFIED:
//                Log.i("MyListVIew", "UNSPECIFIED");
//                break;
//            case MeasureSpec.EXACTLY:
//                Log.i("MyListVIew", "EXACTLY");
//                break;
//            case MeasureSpec.AT_MOST:
//                Log.i("MyListVIew", "AT_MOST");
//                break;
//        }
        int i = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, i);
    }

int i = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);这个代码的含义:
设置一个指定的尺寸大小和指定模式的MeasureSpec值,第一个参数是设置指定的值,第二个参数是设定模式。

Integer.MAX_VALUE >> 2的含义:
MeasureSpec是一个int值,int占4个字节,32位,最高的两位代表的是模式,后面的30位值代表的是尺寸大小。因此Integer.MAX_VALUE >> 2就是最大的数值右移两位(去掉代表模式的位),后面指定模式,刚好就组成了一个Measurespec值。

意思就是在父类最大的范围内去绘制Listview。

你可能感兴趣的:(ScrollView嵌套ListView的问题)