package com.naman14.timber.widgets;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Point;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import com.naman14.timber.R;
public class MultiViewPager extends ViewPager {
private final Point size;
private final Point maxSize;
/**
* 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;
public MultiViewPager(Context context) {
super(context);
size = new Point();
maxSize = new Point();
}
public MultiViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
size = new Point();
maxSize = new Point();
}
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;
}
}
}
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) {
size.set(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
if (mMaxWidth >= 0 || mMaxHeight >= 0) {
maxSize.set(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 the child id
*/
public void setMatchChildWidth(int matchChildWidthResId) {
if (mMatchWidthChildResId != matchChildWidthResId) {
mMatchWidthChildResId = matchChildWidthResId;
mNeedsMeasurePage = true;
}
}
/**
* Sets the maximum size.
*
* @param width in pixels
*/
public void setMaxWidth(int width) {
mMaxWidth = width;
}
/**
* Sets the maximum size.
*
* @param height in pixels
*/
public void setMaxHeight(int height) {
mMaxHeight = height;
}
}