Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ceb6bd12 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add support for stretch overscroll to internal ViewPager" into sc-dev am: 72f1c8bc

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13828644

Change-Id: I2534f2d3092806f3b4cc468e4996b0ef43764b61
parents 58949f6d 72f1c8bc
Loading
Loading
Loading
Loading
+75 −9
Original line number Diff line number Diff line
@@ -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);
@@ -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.
     *
@@ -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;