ViewPager and ViewPager
During Android development, you will often encounter page slide, android. support. v4.view. viewPager makes this implementation easy to use. However, in common use, the width and height of ViewPager are all match_parent, or the height of ViewPager is specified during layout, so everything is normal. The layout was suddenly changed for a long time.
Scenario: ViewPager is used to flip pages in a certain area of the page. However, the attempt in ViewPager is not added during the design period. Therefore, we hope that ViewPager can adapt to the height of child in wrap_content mode. After the layout is well designed, everything is good, because the most common layout settings wrap_content can work well, ViewPager is also a container, so it is taken for granted that it runs normally.
After running the app, you will find that the child I added to the app cannot be displayed, and no exception is found in the tracking code. Okay, let's change the layout, set the ViewPager height to 100dp, and run it again. You can see everything!
You should understand this. ViewPager's wrap_content setting is invalid. He does not calculate his height based on the child view. The onMeasure code of ViewPager is found on the Internet, as shown below:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // For simple implementation, or 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)); // Children are just made to fill our space. mChildWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() - getPaddingLeft() - getPaddingRight(), MeasureSpec.EXACTLY); mChildHeightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY); // Make sure we have created all fragments that we need to have shown. mInLayout = true; populate(); mInLayout = false; // Make sure all children have been properly measured. final int size = getChildCount(); for (int i = 0; i < size; ++i) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { if (DEBUG) Log.v(TAG, "Measuring #" + i + " " + child + ": " + mChildWidthMeasureSpec); child.measure(mChildWidthMeasureSpec, mChildHeightMeasureSpec); } } }
The Code does not use MeasureSpec. makeMeasureSpec can be used to set the actual height. ViewPager, as a container, is different from Linerlayout. Different views can be added to ViewPager, however, they do not have dependency or linear layout. Therefore, if you add n views, the height of each view is different, who do you want it to set its own height? You want to destroy it! The official comments in the Code also illustrate this.
Now that we know the reason, if we need to adapt it to our own height (if we add the same view), we will inherit ViewPager and then override onMeasure.
@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); }
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.