问题:
ViewPager 嵌套多个Fragment,但是每个Fragment高度不一致,导致高度比较小的Fragment底部留有大片空白区域。
解决方法:
参考文章 关于ViewPager高度自适应(随着pager页的高度改变Viewpager的高度)
ViewPager 常用重写类:
1.viewpager嵌套在scrollview中,为了解决viewpager和scorllview的冲突,重写的类
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@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);
}
}
2.为了解决上述空白问题,首先定义一个CustomViewPager类,继承自ViewPager,重写onMeasure方法,重新计算高度
public class CustomViewPager extends ViewPager {
private int current;
private int height = 0;
/** * 保存position与对于的View */
private HashMap mChildrenViews = new LinkedHashMap();
private boolean scrollble = true;
public CustomViewPager(Context context)
{
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (mChildrenViews.size() > current) {
View child = mChildrenViews.get(current);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
height = child.getMeasuredHeight();
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void resetHeight(int current) {
this.current = current;
if (mChildrenViews.size() > current) {
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
if (layoutParams == null) {
layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height);
} else {
layoutParams.height = height;
}
setLayoutParams(layoutParams);
}
}
/** * 保存position与对于的View */
public void setObjectForPosition(View view, int position)
{
mChildrenViews.put(position, view);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!scrollble) {
return true;
}
return super.onTouchEvent(ev);
}
public boolean isScrollble() {
return scrollble;
}
public void setScrollble(boolean scrollble) {
this.scrollble = scrollble;
}
}
使用方法:
首先在Fragment里调用setObjectForPosition方法,存放view和他对应的position:
private int fragmentID=0;
private View rootView=null;
public XXXXXFragment(CustomViewPager vp,int fragmentID)
{
this.vp = vp;
this.fragmentID =fragmentID;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
rootView = inflater.inflate(R.layout.fragment_chart_bp, container, false);
ButterKnife.bind(this, rootView);
vp.setObjectForPosition(rootView,fragmentID);
return rootView;
}
如果从服务端获取数据,得到数据后,重新绘制Fragment,比如显示线形图,或者显示数据为空的提示之类的,需要在绘制之后,重新调用
vp.setObjectForPosition(rootView,fragmentID);
在设置ViewPager时,如果绘制有延迟,需要延迟调用viewPager.resetHeight(position);
private LinkedHashMap titleFragmentMap = new LinkedHashMap<>();
private Fragment fragment1, fragment2, fragment3;
fragment1 = new XXXXXFragment(viewPager,0);
fragment2 = new XXXXXFragment(viewPager,1);
fragment3 = new XXXXXFragment(viewPager,2);
titleFragmentMap.put("日", fragment1);
titleFragmentMap.put("周", fragment2);
titleFragmentMap.put("月", fragment3);
pagerAdapter = new MyFragmentPageAdapter(getChildFragmentManager(), titleFragmentMap);
viewPager.setAdapter(pagerAdapter);
viewPager.setOffscreenPageLimit(3);
viewPager.setCurrentItem(1);
viewPager.addOnPageChangeListener(this);
tabLayout.setupWithViewPager(viewPager);
tabLayout.post(new Runnable()
{
@Override
public void run()
{
TabLayoutUtil.setUpIndicatorWidth(getContext(), tabLayout, 20, 20);
viewPager.resetHeight(1);
}
});
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
}
@Override
public void onPageSelected(int position)
{
viewPager.resetHeight(position);
setInitLineChart();
}
@Override
public void onPageScrollStateChanged(int state)
{
}