viewPager 设置wrapContent 无效,原理和示例,含网上错误版本解析

186 阅读1分钟

原理

1、首先看源码,可知,viewpager不管子view如何,首先将的父viewgroup给他的measureSpec设入。那无论子view如何都和它没关系了。

image.png

正确版本

2、正确版本那么我们肯定是将它的Measure方法重写,将MeasureSpec的值重设。那么我们新写一个viewpager来继承Viewpager就好了。网上有很多版本有问题。我会举例。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int height = 0;
    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        //1、获取子view的param
        ViewGroup.LayoutParams params = child.getLayoutParams();
        //2、将子view 测量
        child.measure(widthMeasureSpec,
                 //获取子view的measureSpec
                 getChildMeasureSpec(heightMeasureSpec,0,params.height));
        //3、获取子view的最高值,作为viewpager的高度
        int h = child.getMeasuredHeight();
        if (h>height)height=h;
    }
    //4、将高度设置进入viewpager需要接受的measureSpec
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,MeasureSpec.EXACTLY);
    //5、如源码所示
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

网上常见错误版本

3、网上有些版本,解析

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int height = 0;
    for(int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        
        
//---------------------------------这种方式将会忽视子viewgroup设计的高度,高度将取决于子viewgroup的子view或者子viewgroup的高度。



        child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int h = child.getMeasuredHeight();
        if(h > height) height = h;
    }

    heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}