网上很多的解释都是对的,但是有所欠缺
直奔主题吧,本问题需要两步来解决,注意哈,两步
首先第一步,当然是要自定义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可以被动态的添加或删除,宽高可能是不确定的。