Skip to content

Instantly share code, notes, and snippets.

@aegis123
Created July 23, 2014 14:57
Show Gist options
  • Save aegis123/a1fdc9f7ef528278b46a to your computer and use it in GitHub Desktop.
Save aegis123/a1fdc9f7ef528278b46a to your computer and use it in GitHub Desktop.
Viewpager bug not accounting for Page Margin
public class SlowViewPager extends ViewGroup {
@Override
public boolean onTouchEvent(MotionEvent ev) {
// all normal Viewpager onTouch code
switch (action & MotionEventCompat.ACTION_MASK) {
case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int initialVelocity = (int) VelocityTrackerCompat.getXVelocity(
velocityTracker, mActivePointerId);
mPopulatePending = true;
final int width = getClientWidth();
final int scrollX = getScrollX();
final ItemInfo ii = infoForCurrentScrollPosition();
final int currentPage = ii.position;
final float marginOffset = width > 0 ? (float) mPageMargin / width : 0;
// Changed to (ii.offset + (marginOffset / 2)) in the calculation of pageOffset
final float pageOffset = (((float) scrollX / width) - (ii.offset + (marginOffset / 2))) / ii.widthFactor;
final int activePointerIndex =
MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final int totalDelta = (int) (x - mInitialMotionX);
int nextPage = determineTargetPage(currentPage, pageOffset, initialVelocity,
totalDelta);
setCurrentItemInternal(nextPage, true, true, initialVelocity);
mActivePointerId = INVALID_POINTER;
endDrag();
needsInvalidate = mLeftEdge.onRelease() | mRightEdge.onRelease();
}
break;
}
// all normal Viewpager onTouch code
return true;
}
private int determineTargetPage(int currentPage, float pageOffset, int velocity, int deltaX) {
int targetPage;
if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) {
targetPage = velocity > 0 ? currentPage : currentPage + 1;
} else {
// Added below to calculate margin ratio.
final int width = getClientWidth();
final float marginRatio = (width > 0 ? (float) mPageMargin / width : 0) / 2;
// made the values 0.4f and 0.6f dynamic based on the width of the viewpager.
final float truncator = currentPage >= mCurItem ? 0.4f + marginRatio : 0.6f - marginRatio;
targetPage = (int) (currentPage + pageOffset + truncator);
}
if (mItems.size() > 0) {
final ItemInfo firstItem = mItems.get(0);
final ItemInfo lastItem = mItems.get(mItems.size() - 1);
// Only let the user target pages we have items for
targetPage = Math.max(firstItem.position, Math.min(targetPage, lastItem.position));
}
return targetPage;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment