Adding overscroll in recents view
Bug: 109828536
Change-Id: I4fe94bd157c2b65f80604751e6f0f7d5d81d058d
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index c81f679..394b950 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -18,6 +18,7 @@
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.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 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 @@
@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 @@
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 @@
* 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 @@
newX = getScrollForPage(mCurrentPage);
}
scrollTo(newX, 0);
- mScroller.setFinalX(newX);
+ mScroller.startScroll(mScroller.getCurrPos(), newX - mScroller.getCurrPos());
forceFinishScroller(true);
}
@@ -349,17 +345,6 @@
@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 @@
overScroll(0);
mWasInOverscroll = false;
}
- mOverScrollX = x;
super.scrollTo(x, y);
}
+
}
private void sendScrollAccessibilityEvent() {
@@ -425,10 +410,9 @@
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 @@
* 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 @@
}
}
- 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) {
- dampedOverScroll(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 @@
} else if (wasFreeScroll) {
snapToPage(getNextPage());
}
-
- setEnableOverscroll(!freeScroll);
}
protected void setEnableOverscroll(boolean enable) {
@@ -1113,6 +1098,8 @@
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 @@
// 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,35 +1133,39 @@
abortScrollerAnimation(true);
}
- float scaleX = getScaleX();
- int vX = (int) (-velocityX * scaleX);
- int initialScrollX = (int) (getScrollX() * scaleX);
+ int initialScrollX = getScrollX();
- 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);
- 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);
+ if (((initialScrollX >= mMaxScrollX) && (isVelocityXLeft || !isFling)) ||
+ ((initialScrollX <= 0) && (!isVelocityXLeft || !isFling))) {
+ mScroller.springBack(getScrollX(), 0, mMaxScrollX);
+ } else {
+ mScroller.setInterpolator(mDefaultInterpolator);
+ mScroller.fling(initialScrollX, -velocityX,
+ 0, mMaxScrollX,
+ Math.round(getWidth() * 0.5f * OVERSCROLL_DAMP_FACTOR));
- mScroller.setFinalX((int) (finalX * getScaleX()));
- // Ensure the scroll/snap doesn't happen too fast;
- int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION
- - mScroller.getDuration();
- if (extraScrollDuration > 0) {
- mScroller.extendDuration(extraScrollDuration);
+ int finalX = mScroller.getFinalPos();
+ mNextPage = getPageNearestToCenterOfScreen(finalX);
+
+ int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1);
+ int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0);
+ 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();
+ if (extraScrollDuration > 0) {
+ mScroller.extendDuration(extraScrollDuration);
+ }
}
}
invalidate();
@@ -1324,7 +1314,7 @@
}
protected boolean isInOverScroll() {
- return (mOverScrollX > mMaxScrollX || mOverScrollX < 0);
+ return (getScrollX() > mMaxScrollX || getScrollX() < 0);
}
protected int getPageSnapDuration() {
@@ -1443,7 +1433,7 @@
mScroller.setInterpolator(mDefaultInterpolator);
}
- mScroller.startScroll(getUnboundedScrollX(), 0, delta, 0, duration);
+ mScroller.startScroll(getUnboundedScrollX(), delta, duration);
updatePageIndicator();