Loading core/java/com/android/internal/widget/ViewPager.java +75 −9 Original line number Diff line number Diff line Loading @@ -353,8 +353,8 @@ public class ViewPager extends ViewGroup { mTouchSlop = configuration.getScaledPagingTouchSlop(); mMinimumVelocity = (int) (MIN_FLING_VELOCITY * density); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mLeftEdge = new EdgeEffect(context); mRightEdge = new EdgeEffect(context); mLeftEdge = new EdgeEffect(context, attrs); mRightEdge = new EdgeEffect(context, attrs); mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density); mCloseEnough = (int) (CLOSE_ENOUGH * density); Loading Loading @@ -386,6 +386,28 @@ public class ViewPager extends ViewGroup { } } /** * Returns the {@link EdgeEffect#getType()} for the edge effects. * @return the {@link EdgeEffect#getType()} for the edge effects. * @attr ref android.R.styleable#EdgeEffect_edgeEffectType */ @EdgeEffect.EdgeEffectType public int getEdgeEffectType() { // Both left and right edge have the same edge effect type return mLeftEdge.getType(); } /** * Sets the {@link EdgeEffect#setType(int)} for the edge effects. * @param type The edge effect type to use for the edge effects. * @attr ref android.R.styleable#EdgeEffect_edgeEffectType */ public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) { mLeftEdge.setType(type); mRightEdge.setType(type); invalidate(); } /** * Set a PagerAdapter that will supply views for this pager as needed. * Loading Loading @@ -1891,7 +1913,7 @@ public class ViewPager extends ViewGroup { } if (mIsBeingDragged) { // Scroll to follow the motion event if (performDrag(x)) { if (performDrag(x, y)) { postInvalidateOnAnimation(); } } Loading @@ -1918,6 +1940,17 @@ public class ViewPager extends ViewGroup { mIsBeingDragged = true; requestParentDisallowInterceptTouchEvent(true); setScrollState(SCROLL_STATE_DRAGGING); } else if (mLeftEdge.getDistance() != 0 || mRightEdge.getDistance() != 0) { // Caught the edge glow animation mIsBeingDragged = true; setScrollState(SCROLL_STATE_DRAGGING); if (mLeftEdge.getDistance() != 0) { mLeftEdge.onPullDistance(0f, 1 - mLastMotionY / getHeight()); } if (mRightEdge.getDistance() != 0) { mRightEdge.onPullDistance(0f, mLastMotionY / getHeight()); } } else { completeScroll(false); mIsBeingDragged = false; Loading Loading @@ -2009,7 +2042,7 @@ public class ViewPager extends ViewGroup { // Scroll to follow the motion event final int activePointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(activePointerIndex); needsInvalidate |= performDrag(x); needsInvalidate |= performDrag(x, ev.getY(activePointerIndex)); } break; case MotionEvent.ACTION_UP: Loading Loading @@ -2080,12 +2113,43 @@ public class ViewPager extends ViewGroup { } } private boolean performDrag(float x) { /** * If either of the horizontal edge glows are currently active, this consumes part or all of * deltaX on the edge glow. * * @param deltaX The pointer motion, in pixels, in the horizontal direction, positive * for moving down and negative for moving up. * @param y The vertical position of the pointer. * @return The amount of <code>deltaX</code> that has been consumed by the * edge glow. */ private float releaseHorizontalGlow(float deltaX, float y) { // First allow releasing existing overscroll effect: float consumed = 0; float displacement = y / getHeight(); float pullDistance = (float) deltaX / getWidth(); if (mLeftEdge.getDistance() != 0) { consumed = -mLeftEdge.onPullDistance(-pullDistance, 1 - displacement); } else if (mRightEdge.getDistance() != 0) { consumed = mRightEdge.onPullDistance(pullDistance, displacement); } return consumed * getWidth(); } private boolean performDrag(float x, float y) { boolean needsInvalidate = false; final float dX = mLastMotionX - x; final int width = getPaddedWidth(); final float deltaX = mLastMotionX - x; mLastMotionX = x; final float releaseConsumed = releaseHorizontalGlow(dX, y); final float deltaX = dX - releaseConsumed; if (releaseConsumed != 0) { needsInvalidate = true; } if (Math.abs(deltaX) < 0.0001f) { // ignore rounding errors from releaseHorizontalGlow() return needsInvalidate; } final EdgeEffect startEdge; final EdgeEffect endEdge; Loading Loading @@ -2128,14 +2192,14 @@ public class ViewPager extends ViewGroup { if (scrollStart < startBound) { if (startAbsolute) { final float over = startBound - scrollStart; startEdge.onPull(Math.abs(over) / width); startEdge.onPullDistance(over / width, 1 - y / getHeight()); needsInvalidate = true; } clampedScrollStart = startBound; } else if (scrollStart > endBound) { if (endAbsolute) { final float over = scrollStart - endBound; endEdge.onPull(Math.abs(over) / width); endEdge.onPullDistance(over / width, y / getHeight()); needsInvalidate = true; } clampedScrollStart = endBound; Loading Loading @@ -2228,7 +2292,9 @@ public class ViewPager extends ViewGroup { */ private int determineTargetPage(int currentPage, float pageOffset, int velocity, int deltaX) { int targetPage; if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) { if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity && mLeftEdge.getDistance() == 0 // don't fling while stretched && mRightEdge.getDistance() == 0) { targetPage = currentPage - (velocity < 0 ? mLeftIncr : 0); } else { final float truncator = currentPage >= mCurItem ? 0.4f : 0.6f; Loading Loading
core/java/com/android/internal/widget/ViewPager.java +75 −9 Original line number Diff line number Diff line Loading @@ -353,8 +353,8 @@ public class ViewPager extends ViewGroup { mTouchSlop = configuration.getScaledPagingTouchSlop(); mMinimumVelocity = (int) (MIN_FLING_VELOCITY * density); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mLeftEdge = new EdgeEffect(context); mRightEdge = new EdgeEffect(context); mLeftEdge = new EdgeEffect(context, attrs); mRightEdge = new EdgeEffect(context, attrs); mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density); mCloseEnough = (int) (CLOSE_ENOUGH * density); Loading Loading @@ -386,6 +386,28 @@ public class ViewPager extends ViewGroup { } } /** * Returns the {@link EdgeEffect#getType()} for the edge effects. * @return the {@link EdgeEffect#getType()} for the edge effects. * @attr ref android.R.styleable#EdgeEffect_edgeEffectType */ @EdgeEffect.EdgeEffectType public int getEdgeEffectType() { // Both left and right edge have the same edge effect type return mLeftEdge.getType(); } /** * Sets the {@link EdgeEffect#setType(int)} for the edge effects. * @param type The edge effect type to use for the edge effects. * @attr ref android.R.styleable#EdgeEffect_edgeEffectType */ public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) { mLeftEdge.setType(type); mRightEdge.setType(type); invalidate(); } /** * Set a PagerAdapter that will supply views for this pager as needed. * Loading Loading @@ -1891,7 +1913,7 @@ public class ViewPager extends ViewGroup { } if (mIsBeingDragged) { // Scroll to follow the motion event if (performDrag(x)) { if (performDrag(x, y)) { postInvalidateOnAnimation(); } } Loading @@ -1918,6 +1940,17 @@ public class ViewPager extends ViewGroup { mIsBeingDragged = true; requestParentDisallowInterceptTouchEvent(true); setScrollState(SCROLL_STATE_DRAGGING); } else if (mLeftEdge.getDistance() != 0 || mRightEdge.getDistance() != 0) { // Caught the edge glow animation mIsBeingDragged = true; setScrollState(SCROLL_STATE_DRAGGING); if (mLeftEdge.getDistance() != 0) { mLeftEdge.onPullDistance(0f, 1 - mLastMotionY / getHeight()); } if (mRightEdge.getDistance() != 0) { mRightEdge.onPullDistance(0f, mLastMotionY / getHeight()); } } else { completeScroll(false); mIsBeingDragged = false; Loading Loading @@ -2009,7 +2042,7 @@ public class ViewPager extends ViewGroup { // Scroll to follow the motion event final int activePointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(activePointerIndex); needsInvalidate |= performDrag(x); needsInvalidate |= performDrag(x, ev.getY(activePointerIndex)); } break; case MotionEvent.ACTION_UP: Loading Loading @@ -2080,12 +2113,43 @@ public class ViewPager extends ViewGroup { } } private boolean performDrag(float x) { /** * If either of the horizontal edge glows are currently active, this consumes part or all of * deltaX on the edge glow. * * @param deltaX The pointer motion, in pixels, in the horizontal direction, positive * for moving down and negative for moving up. * @param y The vertical position of the pointer. * @return The amount of <code>deltaX</code> that has been consumed by the * edge glow. */ private float releaseHorizontalGlow(float deltaX, float y) { // First allow releasing existing overscroll effect: float consumed = 0; float displacement = y / getHeight(); float pullDistance = (float) deltaX / getWidth(); if (mLeftEdge.getDistance() != 0) { consumed = -mLeftEdge.onPullDistance(-pullDistance, 1 - displacement); } else if (mRightEdge.getDistance() != 0) { consumed = mRightEdge.onPullDistance(pullDistance, displacement); } return consumed * getWidth(); } private boolean performDrag(float x, float y) { boolean needsInvalidate = false; final float dX = mLastMotionX - x; final int width = getPaddedWidth(); final float deltaX = mLastMotionX - x; mLastMotionX = x; final float releaseConsumed = releaseHorizontalGlow(dX, y); final float deltaX = dX - releaseConsumed; if (releaseConsumed != 0) { needsInvalidate = true; } if (Math.abs(deltaX) < 0.0001f) { // ignore rounding errors from releaseHorizontalGlow() return needsInvalidate; } final EdgeEffect startEdge; final EdgeEffect endEdge; Loading Loading @@ -2128,14 +2192,14 @@ public class ViewPager extends ViewGroup { if (scrollStart < startBound) { if (startAbsolute) { final float over = startBound - scrollStart; startEdge.onPull(Math.abs(over) / width); startEdge.onPullDistance(over / width, 1 - y / getHeight()); needsInvalidate = true; } clampedScrollStart = startBound; } else if (scrollStart > endBound) { if (endAbsolute) { final float over = scrollStart - endBound; endEdge.onPull(Math.abs(over) / width); endEdge.onPullDistance(over / width, y / getHeight()); needsInvalidate = true; } clampedScrollStart = endBound; Loading Loading @@ -2228,7 +2292,9 @@ public class ViewPager extends ViewGroup { */ private int determineTargetPage(int currentPage, float pageOffset, int velocity, int deltaX) { int targetPage; if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) { if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity && mLeftEdge.getDistance() == 0 // don't fling while stretched && mRightEdge.getDistance() == 0) { targetPage = currentPage - (velocity < 0 ? mLeftIncr : 0); } else { final float truncator = currentPage >= mCurItem ? 0.4f : 0.6f; Loading