diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2021-03-19 21:15:34 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-03-19 21:15:34 +0000 |
| commit | 72f1c8bca41af21a4308f69f3c8e6339a5dc0213 (patch) | |
| tree | 606e50dd9c3c5b6de1c324f041a104a02a2992dc /core/java | |
| parent | e463f4c1513683bd648459608013587df7794895 (diff) | |
| parent | 13cdf67f8a70242d7a422c76fbbb96a78ca26dc3 (diff) | |
Merge "Add support for stretch overscroll to internal ViewPager" into sc-dev
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/com/android/internal/widget/ViewPager.java | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index 6f377b9b228a..93cde3ddb72d 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -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); @@ -387,6 +387,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. * * @param adapter Adapter to use @@ -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(); } } @@ -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; @@ -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: @@ -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; @@ -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; @@ -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; |
