在项目开发中我们会遇到各种各样的奇葩问题,当使用ScrollView嵌套ViewPager的时候,无论高度设为会发生ViewPager不显示的问题。
1、给ViewPager的高度设为固定值
就可以都显示了,但这种情况往往不是想要的。
2、重写ViewPager
这样ViewPager就可以显示了,很多的资料中是这样写的,但是这样的局限是:每个ViewPager的高度都是最高的那个的高度,不能保证每个ViewPager的高度不同。
public class AutoHeightViewPager extends ViewPager {
public AutoHeightViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
// 下面遍历所有child的高度
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
// 采用最大的view的高度
if (h > height) {
height = h;
}
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
重写ViewPager的同时向外暴露一个方法,根据位置动态改变ViewPager的高度。
1、使用map集合存储每个ViewPager的高度
2、暴露一个改变高度的方法,供外部使用
public class ChildViewPager extends ViewPager {
private int current;
/**
* 保存position与对于的View
*/
private HashMap<Integer, Integer> maps = new LinkedHashMap<Integer, Integer>();
public ChildViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChildViewPager(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
// 下面遍历所有child的高度
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
// 采用最大的view的高度
maps.put(i,h);
}
if(getChildCount() > 0){
height = getChildAt(current).getMeasuredHeight();
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void resetHeight(int current) {
this.current = current;
if (maps.size() > current) {
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
if (layoutParams == null) {
layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, maps.get(current));
} else {
layoutParams.height = maps.get(current);
}
setLayoutParams(layoutParams);
}
}
}
在ViewPager的滑动监听事件中调用那个被暴露出来的设置高度的方法
@Override
public void onPageSelected(int position) {
viewPager.resetHeight(position);
}