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

Commit d6ba5041 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adding overscroll in recents view" into ub-launcher3-master

parents 8f7137b7 b7b0135c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
    public RecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
        enableFreeScroll(true);
        setEnableFreeScroll(true);

        mFastFlingVelocity = getResources()
                .getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
+0 −54
Original line number Diff line number Diff line
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3;

import android.animation.TimeInterpolator;
import android.content.Context;
import android.view.animation.Interpolator;
import android.widget.Scroller;

/**
 * Extension of {@link android.widget.Scroller} with the ability to modify the
 * Interpolator post-construction.
 */
public class LauncherScroller extends Scroller {

    private final InterpolatorWrapper mInterpolatorWrapper;

    public LauncherScroller(Context context) {
        this(context, new InterpolatorWrapper());
    }

    private LauncherScroller(Context context, InterpolatorWrapper interpolatorWrapper) {
        super(context, interpolatorWrapper);
        mInterpolatorWrapper = interpolatorWrapper;
    }

    public void setInterpolator(TimeInterpolator interpolator) {
        mInterpolatorWrapper.interpolator = interpolator;
    }

    private static class InterpolatorWrapper implements Interpolator {

        public TimeInterpolator interpolator;

        @Override
        public float getInterpolation(float v) {
            return interpolator == null ? v : interpolator.getInterpolation(v);
        }
    }
}
+65 −75
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.launcher3;

import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
import static com.android.launcher3.touch.OverScroll.OVERSCROLL_DAMP_FACTOR;

import android.animation.LayoutTransition;
import android.animation.TimeInterpolator;
@@ -47,6 +48,7 @@ import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.util.OverScroller;
import com.android.launcher3.util.Thunk;

import java.util.ArrayList;
@@ -82,7 +84,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
    public static final int INVALID_RESTORE_PAGE = -1001;

    private boolean mFreeScroll = false;
    private boolean mSettleOnPageInFreeScroll = false;

    protected int mFlingThresholdVelocity;
    protected int mMinFlingVelocity;
@@ -96,7 +97,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
    @ViewDebug.ExportedProperty(category = "launcher")
    protected int mNextPage = INVALID_PAGE;
    protected int mMaxScrollX;
    protected LauncherScroller mScroller;
    protected OverScroller mScroller;
    private Interpolator mDefaultInterpolator;
    private VelocityTracker mVelocityTracker;
    protected int mPageSpacing = 0;
@@ -122,11 +123,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou

    protected boolean mWasInOverscroll = false;

    // mOverScrollX is equal to getScrollX() when we're within the normal scroll range. Otherwise
    // it is equal to the scaled overscroll position. We use a separate value so as to prevent
    // the screens from continuing to translate beyond the normal bounds.
    protected int mOverScrollX;

    protected int mUnboundedScrollX;

    // Page Indicator
@@ -169,7 +165,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
     * Initializes various states for this workspace.
     */
    protected void init() {
        mScroller = new LauncherScroller(getContext());
        mScroller = new OverScroller(getContext());
        setDefaultInterpolator(Interpolators.SCROLL);
        mCurrentPage = 0;

@@ -244,7 +240,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
            newX = getScrollForPage(mCurrentPage);
        }
        scrollTo(newX, 0);
        mScroller.setFinalX(newX);
        mScroller.startScroll(mScroller.getCurrPos(), newX - mScroller.getCurrPos());
        forceFinishScroller(true);
    }

@@ -349,17 +345,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou

    @Override
    public void scrollTo(int x, int y) {
        // In free scroll mode, we clamp the scrollX
        if (mFreeScroll) {
            // If the scroller is trying to move to a location beyond the maximum allowed
            // in the free scroll mode, we make sure to end the scroll operation.
            if (!mScroller.isFinished() && (x > mMaxScrollX || x < 0)) {
                forceFinishScroller(false);
            }

            x = Utilities.boundToRange(x, 0, mMaxScrollX);
        }

        mUnboundedScrollX = x;

        boolean isXBeforeFirstPage = mIsRtl ? (x > mMaxScrollX) : (x < 0);
@@ -389,9 +374,9 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
                overScroll(0);
                mWasInOverscroll = false;
            }
            mOverScrollX = x;
            super.scrollTo(x, y);
        }

    }

    private void sendScrollAccessibilityEvent() {
@@ -425,10 +410,9 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
    protected boolean computeScrollHelper(boolean shouldInvalidate) {
        if (mScroller.computeScrollOffset()) {
            // Don't bother scrolling if the page does not need to be moved
            if (getUnboundedScrollX() != mScroller.getCurrX()
                    || getScrollY() != mScroller.getCurrY()
                    || mOverScrollX != mScroller.getCurrX()) {
                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            if (getUnboundedScrollX() != mScroller.getCurrPos()
                    || getScrollX() != mScroller.getCurrPos()) {
                scrollTo(mScroller.getCurrPos(), 0);
            }
            if (shouldInvalidate) {
                invalidate();
@@ -865,7 +849,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
                 * otherwise don't.  mScroller.isFinished should be false when
                 * being flinged.
                 */
                final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
                final int xDist = Math.abs(mScroller.getFinalPos() - mScroller.getCurrPos());
                final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop / 3);

                if (finishedScrolling) {
@@ -996,31 +980,34 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
        }
    }

    protected void dampedOverScroll(float amount) {
        if (Float.compare(amount, 0f) == 0) return;
    protected void dampedOverScroll(int amount) {
        if (amount == 0) return;

        int overScrollAmount = OverScroll.dampedScroll(amount, getMeasuredWidth());
        if (amount < 0) {
            mOverScrollX = overScrollAmount;
            super.scrollTo(mOverScrollX, getScrollY());
            super.scrollTo(overScrollAmount, getScrollY());
        } else {
            mOverScrollX = mMaxScrollX + overScrollAmount;
            super.scrollTo(mOverScrollX, getScrollY());
            super.scrollTo(mMaxScrollX + overScrollAmount, getScrollY());
        }
        invalidate();
    }

    protected void overScroll(float amount) {
    protected void overScroll(int amount) {
        if (amount == 0) return;

        if (mFreeScroll && !mScroller.isFinished()) {
            if (amount < 0) {
                super.scrollTo(amount, getScrollY());
            } else {
                super.scrollTo(mMaxScrollX + amount, getScrollY());
            }
        } else {
            dampedOverScroll(amount);
        }


    protected void enableFreeScroll(boolean settleOnPageInFreeScroll) {
        setEnableFreeScroll(true);
        mSettleOnPageInFreeScroll = settleOnPageInFreeScroll;
    }

    private void setEnableFreeScroll(boolean freeScroll) {

    protected void setEnableFreeScroll(boolean freeScroll) {
        boolean wasFreeScroll = mFreeScroll;
        mFreeScroll = freeScroll;

@@ -1029,8 +1016,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
        } else if (wasFreeScroll) {
            snapToPage(getNextPage());
        }

        setEnableOverscroll(!freeScroll);
    }

    protected void setEnableOverscroll(boolean enable) {
@@ -1113,6 +1098,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou

                mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
                boolean isFling = mTotalMotionX > mTouchSlop && shouldFlingForVelocity(velocityX);
                boolean isDeltaXLeft = mIsRtl ? deltaX > 0 : deltaX < 0;
                boolean isVelocityXLeft = mIsRtl ? velocityX > 0 : velocityX < 0;

                if (!mFreeScroll) {
                    // In the case that the page is moved far to one direction and then is flung
@@ -1128,8 +1115,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
                    // We give flings precedence over large moves, which is why we short-circuit our
                    // test for a large move if a fling has been registered. That is, a large
                    // move to the left and fling to the right will register as a fling to the right.
                    boolean isDeltaXLeft = mIsRtl ? deltaX > 0 : deltaX < 0;
                    boolean isVelocityXLeft = mIsRtl ? velocityX > 0 : velocityX < 0;

                    if (((isSignificantMove && !isDeltaXLeft && !isFling) ||
                            (isFling && !isVelocityXLeft)) && mCurrentPage > 0) {
                        finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
@@ -1147,30 +1133,33 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
                        abortScrollerAnimation(true);
                    }

                    float scaleX = getScaleX();
                    int vX = (int) (-velocityX * scaleX);
                    int initialScrollX = (int) (getScrollX() * scaleX);
                    int initialScrollX = getScrollX();

                    if (((initialScrollX >= mMaxScrollX) && (isVelocityXLeft || !isFling)) ||
                            ((initialScrollX <= 0) && (!isVelocityXLeft || !isFling))) {
                        mScroller.springBack(getScrollX(), 0, mMaxScrollX);
                    } else {
                        mScroller.setInterpolator(mDefaultInterpolator);
                    mScroller.fling(initialScrollX,
                            getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);
                    int unscaledScrollX = (int) (mScroller.getFinalX() / scaleX);
                    mNextPage = getPageNearestToCenterOfScreen(unscaledScrollX);
                        mScroller.fling(initialScrollX, -velocityX,
                                0, mMaxScrollX,
                                Math.round(getWidth() * 0.5f * OVERSCROLL_DAMP_FACTOR));

                        int finalX = mScroller.getFinalPos();
                        mNextPage = getPageNearestToCenterOfScreen(finalX);

                        int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1);
                        int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0);
                    if (mSettleOnPageInFreeScroll && unscaledScrollX > 0
                            && unscaledScrollX < mMaxScrollX) {
                        // If scrolling ends in the half of the added space that is closer to the
                        // end, settle to the end. Otherwise snap to the nearest page.
                        // If flinging past one of the ends, don't change the velocity as it will
                        // get stopped at the end anyway.
                        final int finalX = unscaledScrollX < firstPageScroll / 2 ?
                                0 :
                                unscaledScrollX > (lastPageScroll + mMaxScrollX) / 2 ?
                                        mMaxScrollX :
                                        getScrollForPage(mNextPage);

                        mScroller.setFinalX((int) (finalX * getScaleX()));
                        if (finalX > 0 && finalX < mMaxScrollX) {
                            // If scrolling ends in the half of the added space that is closer to
                            // the end, settle to the end. Otherwise snap to the nearest page.
                            // If flinging past one of the ends, don't change the velocity as it
                            // will get stopped at the end anyway.
                            int pageSnappedX = finalX < firstPageScroll / 2 ? 0
                                    : finalX > (lastPageScroll + mMaxScrollX) / 2
                                            ? mMaxScrollX
                                            : getScrollForPage(mNextPage);

                            mScroller.setFinalPos(pageSnappedX);
                            // Ensure the scroll/snap doesn't happen too fast;
                            int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION
                                    - mScroller.getDuration();
@@ -1178,6 +1167,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
                                mScroller.extendDuration(extraScrollDuration);
                            }
                        }
                    }
                    invalidate();
                }
                onScrollInteractionEnd();
@@ -1324,7 +1314,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
    }

    protected boolean isInOverScroll() {
        return (mOverScrollX > mMaxScrollX || mOverScrollX < 0);
        return (getScrollX() > mMaxScrollX || getScrollX() < 0);
    }

    protected int getPageSnapDuration() {
@@ -1443,7 +1433,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
            mScroller.setInterpolator(mDefaultInterpolator);
        }

        mScroller.startScroll(getUnboundedScrollX(), 0, delta, 0, duration);
        mScroller.startScroll(getUnboundedScrollX(), delta, duration);

        updatePageIndicator();

+2 −2
Original line number Diff line number Diff line
@@ -1096,7 +1096,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
    }

    @Override
    protected void overScroll(float amount) {
    protected void overScroll(int amount) {
        boolean shouldScrollOverlay = mLauncherOverlay != null &&
                ((amount <= 0 && !mIsRtl) || (amount >= 0 && mIsRtl));

@@ -1109,7 +1109,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
                mLauncherOverlay.onScrollInteractionBegin();
            }

            mLastOverlayScroll = Math.abs(amount / getMeasuredWidth());
            mLastOverlayScroll = Math.abs(((float) amount) / getMeasuredWidth());
            mLauncherOverlay.onScrollChange(mLastOverlayScroll, mIsRtl);
        } else {
            dampedOverScroll(amount);
+1 −1
Original line number Diff line number Diff line
@@ -493,7 +493,7 @@ public class FolderPagedView extends PagedView<PageIndicatorDots> {
        int delta = scroll - getScrollX();
        if (delta != 0) {
            mScroller.setInterpolator(Interpolators.DEACCEL);
            mScroller.startScroll(getScrollX(), 0, delta, 0, Folder.SCROLL_HINT_DURATION);
            mScroller.startScroll(getScrollX(), delta, Folder.SCROLL_HINT_DURATION);
            invalidate();
        }
    }
Loading