Created
July 23, 2014 14:57
-
-
Save aegis123/a1fdc9f7ef528278b46a to your computer and use it in GitHub Desktop.
Viewpager bug not accounting for Page Margin
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 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