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

Commit b9cda5fd authored by Kirill Grouchnikov's avatar Kirill Grouchnikov
Browse files

Tweaking scroll-related functionality of AbsListView

* Only firing scroll state change to IDLE at the end of the
sequence of emulated mini-fling operations.
* Clarifying the behavior of scrollListBy

Bug: 30114090
Change-Id: I3fe1f851a99ac6392be664be11ca3e05d57ed764
parent b25c0d97
Loading
Loading
Loading
Loading
+41 −16
Original line number Diff line number Diff line
@@ -3003,8 +3003,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            setChildrenDrawingCacheEnabled(false);
            if (mFlingRunnable != null) {
                removeCallbacks(mFlingRunnable);
                // let the fling runnable report it's new state which
                // let the fling runnable report its new state which
                // should be idle
                mFlingRunnable.mSuppressIdleStateChangeCall = false;
                mFlingRunnable.endFling();
                if (mPositionScroller != null) {
                    mPositionScroller.stop();
@@ -4555,6 +4556,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
         */
        private int mLastFlingY;

        /**
         * If true, {@link #endFling()} will not report scroll state change to
         * {@link OnScrollListener#SCROLL_STATE_IDLE}.
         */
        private boolean mSuppressIdleStateChangeCall;

        private final Runnable mCheckFlywheel = new Runnable() {
            @Override
            public void run() {
@@ -4593,6 +4600,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            mScroller.fling(0, initialY, 0, initialVelocity,
                    0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
            mTouchMode = TOUCH_MODE_FLING;
            mSuppressIdleStateChangeCall = false;
            postOnAnimation(this);

            if (PROFILE_FLINGING) {
@@ -4608,6 +4616,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        }

        void startSpringback() {
            mSuppressIdleStateChangeCall = false;
            if (mScroller.springBack(0, mScrollY, 0, 0, 0, 0)) {
                mTouchMode = TOUCH_MODE_OVERFLING;
                invalidate();
@@ -4623,6 +4632,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            mScroller.fling(0, mScrollY, 0, initialVelocity, 0, 0,
                    Integer.MIN_VALUE, Integer.MAX_VALUE, 0, getHeight());
            mTouchMode = TOUCH_MODE_OVERFLING;
            mSuppressIdleStateChangeCall = false;
            invalidate();
            postOnAnimation(this);
        }
@@ -4649,12 +4659,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            postOnAnimation(this);
        }

        void startScroll(int distance, int duration, boolean linear) {
        void startScroll(int distance, int duration, boolean linear,
                boolean suppressEndFlingStateChangeCall) {
            int initialY = distance < 0 ? Integer.MAX_VALUE : 0;
            mLastFlingY = initialY;
            mScroller.setInterpolator(linear ? sLinearInterpolator : null);
            mScroller.startScroll(0, initialY, 0, distance, duration);
            mTouchMode = TOUCH_MODE_FLING;
            mSuppressIdleStateChangeCall = suppressEndFlingStateChangeCall;
            postOnAnimation(this);
        }

@@ -4664,7 +4676,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            removeCallbacks(this);
            removeCallbacks(mCheckFlywheel);

            if (!mSuppressIdleStateChangeCall) {
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            }
            clearScrollingCache();
            mScroller.abortAnimation();

@@ -4907,10 +4921,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
     * @param duration Duration of the scroll animation in milliseconds.
     */
    public void smoothScrollBy(int distance, int duration) {
        smoothScrollBy(distance, duration, false);
        smoothScrollBy(distance, duration, false, false);
    }

    void smoothScrollBy(int distance, int duration, boolean linear) {
    void smoothScrollBy(int distance, int duration, boolean linear,
            boolean suppressEndFlingStateChangeCall) {
        if (mFlingRunnable == null) {
            mFlingRunnable = new FlingRunnable();
        }
@@ -4932,7 +4947,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            }
        } else {
            reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
            mFlingRunnable.startScroll(distance, duration, linear);
            mFlingRunnable.startScroll(distance, duration, linear, suppressEndFlingStateChangeCall);
        }
    }

@@ -5006,6 +5021,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
    /**
     * Scrolls the list items within the view by a specified number of pixels.
     *
     * <p>The actual amount of scroll is capped by the list content viewport height
     * which is the list height minus top and bottom paddings minus one pixel.</p>
     *
     * @param y the amount of pixels to scroll by vertically
     * @see #canScrollList(int)
     */
@@ -7367,7 +7385,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            } else {
                // On-screen, just scroll.
                final int targetTop = getChildAt(mTargetPos - firstPos).getTop();
                smoothScrollBy(targetTop - offset, duration, true);
                smoothScrollBy(targetTop - offset, duration, true, false);
                return;
            }

@@ -7467,7 +7485,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                        Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom;

                final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
                smoothScrollBy(scrollBy, mScrollDuration, true);
                smoothScrollBy(scrollBy, mScrollDuration, true, lastPos < mTargetPos);

                mLastSeenPos = lastPos;
                if (lastPos < mTargetPos) {
@@ -7482,6 +7500,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te

                if (firstPos == mBoundPos || childCount <= nextViewIndex
                        || firstPos + childCount >= mItemCount) {
                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                    return;
                }
                final int nextPos = firstPos + nextViewIndex;
@@ -7498,14 +7517,16 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll);
                if (nextPos < mBoundPos) {
                    smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll),
                            mScrollDuration, true);
                            mScrollDuration, true, true);

                    mLastSeenPos = nextPos;

                    postOnAnimation(this);
                } else  {
                    if (nextViewTop > extraScroll) {
                        smoothScrollBy(nextViewTop - extraScroll, mScrollDuration, true);
                        smoothScrollBy(nextViewTop - extraScroll, mScrollDuration, true, false);
                    } else {
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                    }
                }
                break;
@@ -7526,7 +7547,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                final int extraScroll = firstPos > 0 ?
                        Math.max(mExtraScroll, mListPadding.top) : mListPadding.top;

                smoothScrollBy(firstViewTop - extraScroll, mScrollDuration, true);
                smoothScrollBy(firstViewTop - extraScroll, mScrollDuration, true,
                        firstPos > mTargetPos);

                mLastSeenPos = firstPos;

@@ -7556,13 +7578,16 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                final int extraScroll = Math.max(mListPadding.top, mExtraScroll);
                mLastSeenPos = lastPos;
                if (lastPos > mBoundPos) {
                    smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration, true);
                    smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration, true,
                            true);
                    postOnAnimation(this);
                } else {
                    final int bottom = listHeight - extraScroll;
                    final int lastViewBottom = lastViewTop + lastViewHeight;
                    if (bottom > lastViewBottom) {
                        smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration, true);
                        smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration, true, false);
                    } else {
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                    }
                }
                break;
@@ -7595,12 +7620,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                if (position < firstPos) {
                    final int distance = (int) (-getHeight() * modifier);
                    final int duration = (int) (mScrollDuration * modifier);
                    smoothScrollBy(distance, duration, true);
                    smoothScrollBy(distance, duration, true, true);
                    postOnAnimation(this);
                } else if (position > lastPos) {
                    final int distance = (int) (getHeight() * modifier);
                    final int duration = (int) (mScrollDuration * modifier);
                    smoothScrollBy(distance, duration, true);
                    smoothScrollBy(distance, duration, true, true);
                    postOnAnimation(this);
                } else {
                    // On-screen, just scroll.
@@ -7608,7 +7633,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                    final int distance = targetTop - mOffsetFromTop;
                    final int duration = (int) (mScrollDuration *
                            ((float) Math.abs(distance) / getHeight()));
                    smoothScrollBy(distance, duration, true);
                    smoothScrollBy(distance, duration, true, false);
                }
                break;
            }