解决TabLayout+ViewPager+ListView,当ViewPager设置为Wrap_content,不显示viewpager的问题

网上很多的解释都是对的,但是有所欠缺
直奔主题吧,本问题需要两步来解决,注意哈,两步
首先第一步,当然是要自定义ViewPager了
我这里至贴出关键代码了,网上有的是

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

        int height = 0;
        for(int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            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);
    }

然后run一下,发现 不好用,怎么办呢,因为我们fragment中用的是ListView或者是RecycleListView,大概都一样了,ViewPager为啥设置Wrap-content不能显示,那么ListView就是为啥不显示的
所以我们的ListView也需要自定义一下

public class AdaptiveHeightListView extends ListView {

    public AdaptiveHeightListView(Context context) {
        super(context);
    }

    public AdaptiveHeightListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AdaptiveHeightListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);

        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

再来说一下RecycleListView的解决方案
Fragment中不要使用单独的RecyclerView作为根布局,而是使用一个Linearlayout(高度设置为match_parent)作为根布局,里面再嵌套一个RecyclerView(高度设置为wrap_content)即可。

最后补上为啥会出现这种状况的原因吧
我们直接打开源码就可以看到

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // For simple implementation, our internal size is always 0.
    // We depend on the container to specify the layout size of
    // our view.  We can't really know what it is since we will be
    // adding and removing different arbitrary views and do not
    // want the layout to change as this happens.
    setMeasuredDimension(getDefaultSize(0, widthMeasureSpec),
            getDefaultSize(0, heightMeasureSpec));

    final int measuredWidth = getMeasuredWidth();
    final int maxGutterSize = measuredWidth / 10;
    mGutterSize = Math.min(maxGutterSize, mDefaultGutterSize);
    ...
}

从注释可以看到,viewPager把自己默认的size都是0,然后优先用父布局传过来的宽高,其效果就是宽高没有指定的话就相当于match_parent,完全不考虑子view的属性,因为子view可以被动态的添加或删除,宽高可能是不确定的。

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页