Last active
February 8, 2018 03:17
-
-
Save mrleolink/83968489070437a059f6a005307549cd to your computer and use it in GitHub Desktop.
ViewPager that wraps current page's height
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
import android.content.Context; | |
import android.support.annotation.Nullable; | |
import android.support.v4.view.PagerAdapter; | |
import android.support.v4.view.ViewPager; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.view.ViewGroup; | |
/** | |
* {@link ViewPager} that wraps current page's height | |
* | |
* @author Leo | |
*/ | |
public class WrapContentViewPager extends ViewPager { | |
private Adapter mAdapter; | |
public WrapContentViewPager(Context context) { | |
this(context, null); | |
} | |
public WrapContentViewPager(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
@Override | |
public void setAdapter(PagerAdapter adapter) { | |
if (!(adapter instanceof Adapter)) | |
throw new IllegalArgumentException("Adapter of WrapContentViewPager has to implement WrapContentViewPager.Adapter"); | |
mAdapter = (Adapter) adapter; | |
super.setAdapter(adapter); | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
int height = 0; | |
View child = mAdapter == null ? null : mAdapter.getCurrentPageView(getCurrentItem()); | |
if (child != null) { | |
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); | |
int h = child.getMeasuredHeight(); | |
if (h > height) height = h; | |
} else if (getAdapter() != null && getAdapter().getCount() > 0) { | |
post(this::requestLayout); // recur until we can get reference to the current page view | |
} | |
if (height != 0) { | |
height += getPaddingTop() + getPaddingBottom(); // take padding into account | |
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); | |
} | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
} | |
public interface Adapter { | |
/** | |
* <p>Get view for currently selected page of the ViewPager. | |
* <p>Since this method is only called to get the View of current page, so implementation of this method should | |
* NOT keep references to ALL pages of the ViewPager, but utilize | |
* {@link PagerAdapter#destroyItem(ViewGroup, int, Object)} to remove unnecessary references instead. | |
* <p>Or you can override {@link PagerAdapter#setPrimaryItem(ViewGroup, int, Object)} to grab reference to | |
* current view. | |
* | |
* @param currentPosition current page of the ViewPager | |
* @return {@link View} instance of the current page | |
*/ | |
@Nullable | |
View getCurrentPageView(int currentPosition); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment