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

Commit 4742212b authored by George Mount's avatar George Mount Committed by Automerger Merge Worker
Browse files

Merge "Fling while overscrolled: ScrollView/HorizontalScrollView" into sc-dev am: ee5ed9df

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

Change-Id: Ic5959ad85509c653abd1088868c162807d4d72eb
parents cfc847c0 ee5ed9df
Loading
Loading
Loading
Loading
+29 −19
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ import android.view.animation.AnimationUtils;
import android.view.inspector.InspectableProperty;
import android.view.inspector.InspectableProperty;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;


import java.util.List;
import java.util.List;


@@ -86,19 +87,23 @@ public class HorizontalScrollView extends FrameLayout {
     *
     *
     * Even though this field is practically final, we cannot make it final because there are apps
     * Even though this field is practically final, we cannot make it final because there are apps
     * setting it via reflection and they need to keep working until they target Q.
     * setting it via reflection and they need to keep working until they target Q.
     * @hide
     */
     */
    @NonNull
    @NonNull
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124053130)
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124053130)
    private EdgeEffect mEdgeGlowLeft;
    @VisibleForTesting
    public EdgeEffect mEdgeGlowLeft;


    /**
    /**
     * Tracks the state of the bottom edge glow.
     * Tracks the state of the bottom edge glow.
     *
     *
     * Even though this field is practically final, we cannot make it final because there are apps
     * Even though this field is practically final, we cannot make it final because there are apps
     * setting it via reflection and they need to keep working until they target Q.
     * setting it via reflection and they need to keep working until they target Q.
     * @hide
     */
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124052619)
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124052619)
    private EdgeEffect mEdgeGlowRight;
    @VisibleForTesting
    public EdgeEffect mEdgeGlowRight;


    /**
    /**
     * Position of the last motion event.
     * Position of the last motion event.
@@ -774,11 +779,8 @@ public class HorizontalScrollView extends FrameLayout {


                    // Calling overScrollBy will call onOverScrolled, which
                    // Calling overScrollBy will call onOverScrolled, which
                    // calls onScrollChanged if applicable.
                    // calls onScrollChanged if applicable.
                    if (overScrollBy(deltaX, 0, mScrollX, 0, range, 0,
                    overScrollBy(deltaX, 0, mScrollX, 0, range, 0,
                            mOverscrollDistance, 0, true)) {
                            mOverscrollDistance, 0, true);
                        // Break our velocity if we hit a scroll barrier.
                        mVelocityTracker.clear();
                    }


                    if (canOverscroll && deltaX != 0f) {
                    if (canOverscroll && deltaX != 0f) {
                        final int pulledToX = oldX + deltaX;
                        final int pulledToX = oldX + deltaX;
@@ -1737,10 +1739,17 @@ public class HorizontalScrollView extends FrameLayout {
    public void fling(int velocityX) {
    public void fling(int velocityX) {
        if (getChildCount() > 0) {
        if (getChildCount() > 0) {
            int width = getWidth() - mPaddingRight - mPaddingLeft;
            int width = getWidth() - mPaddingRight - mPaddingLeft;
            int right = getChildAt(0).getWidth();
            int right = getChildAt(0).getRight() - mPaddingLeft;

            int maxScroll = Math.max(0, right - width);


            if (mScrollX == 0 && !mEdgeGlowLeft.isFinished()) {
                mEdgeGlowLeft.onAbsorb(-velocityX);
            } else if (mScrollX == maxScroll && !mEdgeGlowRight.isFinished()) {
                mEdgeGlowRight.onAbsorb(velocityX);
            } else {
                mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
                mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
                    Math.max(0, right - width), 0, 0, width/2, 0);
                        maxScroll, 0, 0, width / 2, 0);


                final boolean movingRight = velocityX > 0;
                final boolean movingRight = velocityX > 0;


@@ -1755,6 +1764,7 @@ public class HorizontalScrollView extends FrameLayout {
                if (newFocused != currentFocused) {
                if (newFocused != currentFocused) {
                    newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
                    newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
                }
                }
            }


            postInvalidateOnAnimation();
            postInvalidateOnAnimation();
        }
        }
+14 −3
Original line number Original line Diff line number Diff line
@@ -49,6 +49,7 @@ import android.view.animation.AnimationUtils;
import android.view.inspector.InspectableProperty;
import android.view.inspector.InspectableProperty;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;


import java.util.List;
import java.util.List;


@@ -95,20 +96,24 @@ public class ScrollView extends FrameLayout {
     *
     *
     * Even though this field is practically final, we cannot make it final because there are apps
     * Even though this field is practically final, we cannot make it final because there are apps
     * setting it via reflection and they need to keep working until they target Q.
     * setting it via reflection and they need to keep working until they target Q.
     * @hide
     */
     */
    @NonNull
    @NonNull
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768600)
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768600)
    private EdgeEffect mEdgeGlowTop;
    @VisibleForTesting
    public EdgeEffect mEdgeGlowTop;


    /**
    /**
     * Tracks the state of the bottom edge glow.
     * Tracks the state of the bottom edge glow.
     *
     *
     * Even though this field is practically final, we cannot make it final because there are apps
     * Even though this field is practically final, we cannot make it final because there are apps
     * setting it via reflection and they need to keep working until they target Q.
     * setting it via reflection and they need to keep working until they target Q.
     * @hide
     */
     */
    @NonNull
    @NonNull
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769386)
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769386)
    private EdgeEffect mEdgeGlowBottom;
    @VisibleForTesting
    public EdgeEffect mEdgeGlowBottom;


    /**
    /**
     * Position of the last motion event.
     * Position of the last motion event.
@@ -1791,9 +1796,15 @@ public class ScrollView extends FrameLayout {
        final boolean canFling = (mScrollY > 0 || velocityY > 0) &&
        final boolean canFling = (mScrollY > 0 || velocityY > 0) &&
                (mScrollY < getScrollRange() || velocityY < 0);
                (mScrollY < getScrollRange() || velocityY < 0);
        if (!dispatchNestedPreFling(0, velocityY)) {
        if (!dispatchNestedPreFling(0, velocityY)) {
            dispatchNestedFling(0, velocityY, canFling);
            final boolean consumed = dispatchNestedFling(0, velocityY, canFling);
            if (canFling) {
            if (canFling) {
                fling(velocityY);
                fling(velocityY);
            } else if (!consumed) {
                if (!mEdgeGlowTop.isFinished()) {
                    mEdgeGlowTop.onAbsorb(-velocityY);
                } else if (!mEdgeGlowBottom.isFinished()) {
                    mEdgeGlowBottom.onAbsorb(velocityY);
                }
            }
            }
        }
        }
    }
    }