Last active
August 29, 2015 14:06
-
-
Save pflammertsma/754d55a11e4329baee77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class MultiViewPager extends ViewPager { | |
| /** | |
| * Maximum size. | |
| */ | |
| private int mMaxWidth = -1; | |
| /** | |
| * Maximum size. | |
| */ | |
| private int mMaxHeight = -1; | |
| /** | |
| * Child view inside a page to match the page size against. | |
| */ | |
| private int mMatchWidthChildResId; | |
| /** | |
| * Internal state to schedule a new measurement pass. | |
| */ | |
| private boolean mNeedsMeasurePage; | |
| private static void constrainTo(Point size, Point maxSize) { | |
| if (maxSize.x >= 0) { | |
| if (size.x > maxSize.x) { | |
| size.x = maxSize.x; | |
| } | |
| } | |
| if (maxSize.y >= 0) { | |
| if (size.y > maxSize.y) { | |
| size.y = maxSize.y; | |
| } | |
| } | |
| } | |
| public MultiViewPager(Context context) { | |
| super(context); | |
| } | |
| public MultiViewPager(Context context, AttributeSet attrs) { | |
| super(context, attrs); | |
| init(context, attrs); | |
| } | |
| private void init(Context context, AttributeSet attrs) { | |
| setClipChildren(false); | |
| TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MultiViewPager); | |
| setMaxWidth(ta.getDimensionPixelSize(R.styleable.MultiViewPager_android_maxWidth, -1)); | |
| setMaxHeight(ta.getDimensionPixelSize(R.styleable.MultiViewPager_android_maxHeight, -1)); | |
| setMatchChildWidth(ta.getResourceId(R.styleable.MultiViewPager_matchChildWidth, 0)); | |
| ta.recycle(); | |
| } | |
| @Override | |
| protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
| Point size = new Point( | |
| MeasureSpec.getSize(widthMeasureSpec), | |
| MeasureSpec.getSize(heightMeasureSpec)); | |
| if (mMaxWidth >= 0 || mMaxHeight >= 0) { | |
| Point maxSize = new Point(mMaxWidth, mMaxHeight); | |
| constrainTo(size, maxSize); | |
| widthMeasureSpec = MeasureSpec.makeMeasureSpec( | |
| size.x, | |
| MeasureSpec.EXACTLY); | |
| heightMeasureSpec = MeasureSpec.makeMeasureSpec( | |
| size.y, | |
| MeasureSpec.EXACTLY); | |
| } | |
| super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
| onMeasurePage(widthMeasureSpec, heightMeasureSpec); | |
| } | |
| protected void onMeasurePage(int widthMeasureSpec, int heightMeasureSpec) { | |
| // Only measure if a measurement pass was scheduled | |
| if (!mNeedsMeasurePage) { | |
| return; | |
| } | |
| if (mMatchWidthChildResId == 0) { | |
| mNeedsMeasurePage = false; | |
| } else if (getChildCount() > 0) { | |
| View child = getChildAt(0); | |
| child.measure(widthMeasureSpec, heightMeasureSpec); | |
| int pageWidth = child.getMeasuredWidth(); | |
| View match = child.findViewById(mMatchWidthChildResId); | |
| if (match == null) { | |
| throw new NullPointerException( | |
| "MatchWithChildResId did not find that ID in the first fragment of the ViewPager; " | |
| + "is that view defined in the child view's layout? Note that MultiViewPager " | |
| + "only measures the child for index 0."); | |
| } | |
| int childWidth = match.getMeasuredWidth(); | |
| // Check that the measurement was successful | |
| if (childWidth > 0) { | |
| mNeedsMeasurePage = false; | |
| int difference = pageWidth - childWidth; | |
| setPageMargin(-difference); | |
| int offscreen = (int) Math.ceil((float) pageWidth / (float) childWidth) + 1; | |
| setOffscreenPageLimit(offscreen); | |
| requestLayout(); | |
| } | |
| } | |
| } | |
| @Override | |
| protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
| super.onSizeChanged(w, h, oldw, oldh); | |
| // Schedule a new measurement pass as the dimensions have changed | |
| mNeedsMeasurePage = true; | |
| } | |
| /** | |
| * Sets the child view inside a page to match the page size against. | |
| * | |
| * @param matchChildWidthResId | |
| */ | |
| public void setMatchChildWidth(int matchChildWidthResId) { | |
| if (mMatchWidthChildResId != matchChildWidthResId) { | |
| mMatchWidthChildResId = matchChildWidthResId; | |
| mNeedsMeasurePage = true; | |
| } | |
| } | |
| /** | |
| * Sets the maximum size. | |
| * | |
| * @param width | |
| */ | |
| public void setMaxWidth(int width) { | |
| mMaxWidth = width; | |
| } | |
| /** | |
| * Sets the maximum size. | |
| * | |
| * @param height | |
| */ | |
| public void setMaxHeight(int height) { | |
| mMaxHeight = height; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment