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

Commit 9b56a605 authored by George Mount's avatar George Mount
Browse files

Calculate velocity when using smooth scrolling

Fixes: 329933898

When using scrolling, Overscroller now calculates
the current velocity so that it can be used with
ScrollView, HorizontalScrollView, and AbsListView.

Test: new tests for ScrollView and HorizontalScrollView
Change-Id: I0870b12f2afa751d12a4afa8ce473451c4e93ed4
parent 1cc982e9
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -299,8 +299,10 @@ public class OverScroller {
                final int duration = mScrollerX.mDuration;
                if (elapsedTime < duration) {
                    final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
                    mScrollerX.updateScroll(q);
                    mScrollerY.updateScroll(q);
                    final float q2 =
                            mInterpolator.getInterpolation((elapsedTime - 1) / (float) duration);
                    mScrollerX.updateScroll(q, q2);
                    mScrollerY.updateScroll(q, q2);
                } else {
                    abortAnimation();
                }
@@ -642,8 +644,11 @@ public class OverScroller {
                    * 0.84f; // look and feel tuning
        }

        void updateScroll(float q) {
            mCurrentPosition = mStart + Math.round(q * (mFinal - mStart));
        void updateScroll(float q, float q2) {
            int distance = mFinal - mStart;
            mCurrentPosition = mStart + Math.round(q * distance);
            // q2 is 1ms before q1
            mCurrVelocity = 1000f * (q - q2) * distance;
        }

        /*
+15 −15
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/horizontal_scroll_view">

        <LinearLayout
@@ -133,31 +133,31 @@
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            android:orientation="horizontal">
            <View
                android:background="#00F"
                android:layout_width="90dp"
                android:layout_height="50dp"/>
                android:layout_width="100dp"
                android:layout_height="90dp"/>
            <View
                android:background="#0FF"
                android:layout_width="90dp"
                android:layout_height="50dp"/>
                android:layout_width="100dp"
                android:layout_height="90dp"/>
            <View
                android:background="#0F0"
                android:layout_width="90dp"
                android:layout_height="50dp"/>
                android:layout_width="100dp"
                android:layout_height="90dp"/>
            <View
                android:background="#FF0"
                android:layout_width="90dp"
                android:layout_height="50dp"/>
                android:layout_width="100dp"
                android:layout_height="90dp"/>
            <View
                android:background="#F00"
                android:layout_width="90dp"
                android:layout_height="50dp"/>
                android:layout_width="100dp"
                android:layout_height="90dp"/>
            <View
                android:background="#F0F"
                android:layout_width="90dp"
                android:layout_height="50dp"/>
                android:layout_width="100dp"
                android:layout_height="90dp"/>
        </LinearLayout>
    </view>
</LinearLayout>
+2 −2
Original line number Diff line number Diff line
@@ -18,10 +18,10 @@
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    android:orientation="horizontal">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/scroll_view">

+22 −6
Original line number Diff line number Diff line
@@ -99,13 +99,29 @@ public class HorizontalScrollViewFunctionalTest {
            mMyHorizontalScrollView.setFrameContentVelocity(0);
        });
        // set setFrameContentVelocity shouldn't do anything.
        assertEquals(mMyHorizontalScrollView.isSetVelocityCalled, false);
        assertTrue(mMyHorizontalScrollView.isSetVelocityCalled);
        assertEquals(0f, mMyHorizontalScrollView.velocity, 0f);
        mMyHorizontalScrollView.isSetVelocityCalled = false;

        mActivityRule.runOnUiThread(() -> {
            mMyHorizontalScrollView.fling(100);
        });
        // set setFrameContentVelocity should be called when fling.
        assertEquals(mMyHorizontalScrollView.isSetVelocityCalled, true);
        assertTrue(mMyHorizontalScrollView.isSetVelocityCalled);
        assertTrue(mMyHorizontalScrollView.velocity > 0f);
    }

    @Test
    @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
    public void hasVelocityInSmoothScrollBy() throws Throwable {
        int maxScroll = mMyHorizontalScrollView.getChildAt(0).getWidth()
                - mMyHorizontalScrollView.getWidth();
        mActivityRule.runOnUiThread(() -> {
            mMyHorizontalScrollView.smoothScrollTo(maxScroll, 0);
        });
        PollingCheck.waitFor(() -> mMyHorizontalScrollView.getScrollX() != 0);
        assertTrue(mMyHorizontalScrollView.isSetVelocityCalled);
        assertTrue(mMyHorizontalScrollView.velocity > 0f);
    }

    static class WatchedEdgeEffect extends EdgeEffect {
@@ -122,9 +138,10 @@ public class HorizontalScrollViewFunctionalTest {
        }
    }

    public static class MyHorizontalScrollView extends ScrollView {
    public static class MyHorizontalScrollView extends HorizontalScrollView {

        public boolean isSetVelocityCalled;
        public float velocity;

        public MyHorizontalScrollView(Context context) {
            super(context);
@@ -140,9 +157,8 @@ public class HorizontalScrollViewFunctionalTest {

        @Override
        public void setFrameContentVelocity(float pixelsPerSecond) {
            if (pixelsPerSecond != 0) {
            isSetVelocityCalled = true;
            }
            velocity = pixelsPerSecond;
        }
    }
}
+22 −5
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.widget;
import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import android.content.Context;
@@ -98,13 +99,28 @@ public class ScrollViewFunctionalTest {
            mMyScrollView.setFrameContentVelocity(0);
        });
        // set setFrameContentVelocity shouldn't do anything.
        assertEquals(mMyScrollView.isSetVelocityCalled, false);
        assertTrue(mMyScrollView.isSetVelocityCalled);
        assertEquals(0f, mMyScrollView.velocity, 0f);
        mMyScrollView.isSetVelocityCalled = false;

        mActivityRule.runOnUiThread(() -> {
            mMyScrollView.fling(100);
        });
        // set setFrameContentVelocity should be called when fling.
        assertEquals(mMyScrollView.isSetVelocityCalled, true);
        assertTrue(mMyScrollView.isSetVelocityCalled);
        assertNotEquals(0f, mMyScrollView.velocity, 0.01f);
    }

    @Test
    @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
    public void hasVelocityInSmoothScrollBy() throws Throwable {
        int maxScroll = mMyScrollView.getChildAt(0).getHeight() - mMyScrollView.getHeight();
        mActivityRule.runOnUiThread(() -> {
            mMyScrollView.smoothScrollTo(0, maxScroll);
        });
        PollingCheck.waitFor(() -> mMyScrollView.getScrollY() != 0);
        assertTrue(mMyScrollView.isSetVelocityCalled);
        assertTrue(mMyScrollView.velocity > 0f);
    }

    static class WatchedEdgeEffect extends EdgeEffect {
@@ -125,6 +141,8 @@ public class ScrollViewFunctionalTest {

        public boolean isSetVelocityCalled;

        public float velocity;

        public MyScrollView(Context context) {
            super(context);
        }
@@ -139,9 +157,8 @@ public class ScrollViewFunctionalTest {

        @Override
        public void setFrameContentVelocity(float pixelsPerSecond) {
            if (pixelsPerSecond != 0) {
            isSetVelocityCalled = true;
            }
            velocity = pixelsPerSecond;
        }
    }
}