如果不处理的话,viewpager是统一的高度,fragment的底部会空白一段距离,处理之后,viewpager的高度跟随fragment保持一致。
首先是viewpager
/** * 自适应高度的 viewpager */ public class WrapContentHeightViewPager extends ViewPager { private int current; private int height = 0; private boolean scrollble = true; /** * 保存position与对于的View */ private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>(); public WrapContentHeightViewPager(Context context) { super(context); } public WrapContentHeightViewPager(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); if (mChildrenViews.size() > current) { View child = mChildrenViews.get(current); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); height = child.getMeasuredHeight(); } if (mChildrenViews.size() != 0) { heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); } LogUtil.d("height","onMeasure="+height); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public void resetHeight(int current) { this.current = current; if (mChildrenViews.size() > current) { ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) getLayoutParams(); if (layoutParams == null) { layoutParams = new ConstraintLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height); } else { layoutParams.height = height; } setLayoutParams(layoutParams); LogUtil.d("height","height="+height); } } /** * 保存position与对于的View */ public void setObjectForPosition(View view, int position) { mChildrenViews.put(position, view); } @Override public void setCurrentItem(int item) { //去除页面切换时的滑动翻页效果 super.setCurrentItem(item, false); } }
第一步;在activity中,布局中使用自定义的viewpager,
第二步,在activity中把viewpager传递到fragment中去,并且在fragment中存储 下标和view。
activity中:把viewpager传递给fragment
fragment0.setPager(viewpager); fragment1.setPager(viewpager); fragment2.setPager(viewpager);
fragment中:
WrapContentHeightViewPager pager; public void setPager(WrapContentHeightViewPager pager) { this.pager = pager; }
fragment的初始化中:传入view和下标
pager.setObjectForPosition(getView(),pagerIndex);
第三步:在切换tab的时候,重新测量viewpager的高度
/** * tab切换时候的监听 */ class TabSelectListener implements TabLayout.OnTabSelectedListener { @Override public void onTabSelected(TabLayout.Tab tab) { /**在这里记录TabLayout选中后内容更新已读标记**/ if (!ConstellationActivity.this.isFinishing()) { int position = tab.getPosition(); viewpager.resetHeight(position); if (null != tab.getCustomView()) { View line = tab.getCustomView().findViewById(R.id.view_line); line.setVisibility(View.VISIBLE); } } }
}
这样,fragment的高度和viewpager的高度保持一致。