API refactoring for OverScroller.
OverScroller is no longer a child class of Scroller and several
Scroller methods that do not make sense for OverScroller and could
cause misbehaving edge cases have been removed or hidden and
deprecated.
Change-Id: Ie055b607bd3b36c47ab9798d5c9518aef686b474
diff --git a/api/current.xml b/api/current.xml
index d282e06..03d8a3a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -205705,6 +205705,331 @@
</parameter>
</method>
</interface>
+<class name="OverScroller"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+</constructor>
+<constructor name="OverScroller"
+ type="android.widget.OverScroller"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="interpolator" type="android.view.animation.Interpolator">
+</parameter>
+<parameter name="bounceCoefficientX" type="float">
+</parameter>
+<parameter name="bounceCoefficientY" type="float">
+</parameter>
+</constructor>
+<method name="abortAnimation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="computeScrollOffset"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="fling"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="velocityX" type="int">
+</parameter>
+<parameter name="velocityY" type="int">
+</parameter>
+<parameter name="minX" type="int">
+</parameter>
+<parameter name="maxX" type="int">
+</parameter>
+<parameter name="minY" type="int">
+</parameter>
+<parameter name="maxY" type="int">
+</parameter>
+</method>
+<method name="fling"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="velocityX" type="int">
+</parameter>
+<parameter name="velocityY" type="int">
+</parameter>
+<parameter name="minX" type="int">
+</parameter>
+<parameter name="maxX" type="int">
+</parameter>
+<parameter name="minY" type="int">
+</parameter>
+<parameter name="maxY" type="int">
+</parameter>
+<parameter name="overX" type="int">
+</parameter>
+<parameter name="overY" type="int">
+</parameter>
+</method>
+<method name="forceFinished"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="finished" type="boolean">
+</parameter>
+</method>
+<method name="getCurrX"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCurrY"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFinalX"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFinalY"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStartX"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStartY"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isFinished"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isOverscrolled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="notifyHorizontalEdgeReached"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="finalX" type="int">
+</parameter>
+<parameter name="overX" type="int">
+</parameter>
+</method>
+<method name="notifyVerticalEdgeReached"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="finalY" type="int">
+</parameter>
+<parameter name="overY" type="int">
+</parameter>
+</method>
+<method name="springback"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="minX" type="int">
+</parameter>
+<parameter name="maxX" type="int">
+</parameter>
+<parameter name="minY" type="int">
+</parameter>
+<parameter name="maxY" type="int">
+</parameter>
+</method>
+<method name="startScroll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="dx" type="int">
+</parameter>
+<parameter name="dy" type="int">
+</parameter>
+</method>
+<method name="startScroll"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="startX" type="int">
+</parameter>
+<parameter name="startY" type="int">
+</parameter>
+<parameter name="dx" type="int">
+</parameter>
+<parameter name="dy" type="int">
+</parameter>
+<parameter name="duration" type="int">
+</parameter>
+</method>
+</class>
<class name="PopupWindow"
extends="java.lang.Object"
abstract="false"
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9150b5e..44fd939 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2610,14 +2610,7 @@
}
void edgeReached() {
- mScroller.notifyVerticalEdgeReached(mScrollY, 0, Integer.MAX_VALUE);
- mTouchMode = TOUCH_MODE_OVERFLING;
- invalidate();
- post(this);
- }
-
- void marginReached() {
- mScroller.notifyVerticalBoundaryReached(mScrollY, 0);
+ mScroller.notifyVerticalEdgeReached(mScrollY, 0, getOverscrollMax());
mTouchMode = TOUCH_MODE_OVERFLING;
invalidate();
post(this);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 06da5fa..3bd4767 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -599,6 +599,7 @@
} else {
super.scrollTo(scrollX, scrollY);
}
+ awakenScrollBars();
}
private int getOverscrollMax() {
@@ -961,7 +962,6 @@
dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
mScroller.startScroll(scrollX, mScrollY, dx, 0);
- awakenScrollBars(mScroller.getDuration());
invalidate();
} else {
if (!mScroller.isFinished()) {
@@ -1319,7 +1319,6 @@
mScrollViewMovedFocus = false;
}
- awakenScrollBars(mScroller.getDuration());
invalidate();
}
}
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 48e7493..e8d92de 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -17,21 +17,27 @@
package android.widget;
import android.content.Context;
+import android.util.FloatMath;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import android.widget.Scroller.MagneticScroller;
/**
* This class encapsulates scrolling with the ability to overshoot the bounds
- * of a scrolling operation. This class attempts to be a drop-in replacement
- * for {@link android.widget.Scroller} in most cases.
- *
- * @hide Pending API approval
+ * of a scrolling operation. This class is a drop-in replacement for
+ * {@link android.widget.Scroller} in most cases.
*/
-public class OverScroller extends Scroller {
+public class OverScroller {
+ private int mMode;
- // Identical to mScrollers, but casted to MagneticOverScroller.
- private MagneticOverScroller mOverScrollerX;
- private MagneticOverScroller mOverScrollerY;
+ private MagneticOverScroller mScrollerX;
+ private MagneticOverScroller mScrollerY;
+
+ private final Interpolator mInterpolator;
+
+ private static final int DEFAULT_DURATION = 250;
+ private static final int SCROLL_MODE = 0;
+ private static final int FLING_MODE = 1;
/**
* Creates an OverScroller with a viscous fluid scroll interpolator.
@@ -64,15 +70,259 @@
*/
public OverScroller(Context context, Interpolator interpolator,
float bounceCoefficientX, float bounceCoefficientY) {
- super(context, interpolator);
- mOverScrollerX.setBounceCoefficient(bounceCoefficientX);
- mOverScrollerY.setBounceCoefficient(bounceCoefficientY);
+ mInterpolator = interpolator;
+ mScrollerX = new MagneticOverScroller();
+ mScrollerY = new MagneticOverScroller();
+ MagneticScroller.initializeFromContext(context);
+
+ mScrollerX.setBounceCoefficient(bounceCoefficientX);
+ mScrollerY.setBounceCoefficient(bounceCoefficientY);
}
- @Override
- void instantiateScrollers() {
- mScrollerX = mOverScrollerX = new MagneticOverScroller();
- mScrollerY = mOverScrollerY = new MagneticOverScroller();
+ /**
+ *
+ * Returns whether the scroller has finished scrolling.
+ *
+ * @return True if the scroller has finished scrolling, false otherwise.
+ */
+ public final boolean isFinished() {
+ return mScrollerX.mFinished && mScrollerY.mFinished;
+ }
+
+ /**
+ * Force the finished field to a particular value. Contrary to
+ * {@link #abortAnimation()}, forcing the animation to finished
+ * does NOT cause the scroller to move to the final x and y
+ * position.
+ *
+ * @param finished The new finished value.
+ */
+ public final void forceFinished(boolean finished) {
+ mScrollerX.mFinished = mScrollerY.mFinished = finished;
+ }
+
+ /**
+ * Returns the current X offset in the scroll.
+ *
+ * @return The new X offset as an absolute distance from the origin.
+ */
+ public final int getCurrX() {
+ return mScrollerX.mCurrentPosition;
+ }
+
+ /**
+ * Returns the current Y offset in the scroll.
+ *
+ * @return The new Y offset as an absolute distance from the origin.
+ */
+ public final int getCurrY() {
+ return mScrollerY.mCurrentPosition;
+ }
+
+ /**
+ * @hide
+ * Returns the current velocity.
+ *
+ * @return The original velocity less the deceleration, norm of the X and Y velocity vector.
+ */
+ public float getCurrVelocity() {
+ float squaredNorm = mScrollerX.mCurrVelocity * mScrollerX.mCurrVelocity;
+ squaredNorm += mScrollerY.mCurrVelocity * mScrollerY.mCurrVelocity;
+ return FloatMath.sqrt(squaredNorm);
+ }
+
+ /**
+ * Returns the start X offset in the scroll.
+ *
+ * @return The start X offset as an absolute distance from the origin.
+ */
+ public final int getStartX() {
+ return mScrollerX.mStart;
+ }
+
+ /**
+ * Returns the start Y offset in the scroll.
+ *
+ * @return The start Y offset as an absolute distance from the origin.
+ */
+ public final int getStartY() {
+ return mScrollerY.mStart;
+ }
+
+ /**
+ * Returns where the scroll will end. Valid only for "fling" scrolls.
+ *
+ * @return The final X offset as an absolute distance from the origin.
+ */
+ public final int getFinalX() {
+ return mScrollerX.mFinal;
+ }
+
+ /**
+ * Returns where the scroll will end. Valid only for "fling" scrolls.
+ *
+ * @return The final Y offset as an absolute distance from the origin.
+ */
+ public final int getFinalY() {
+ return mScrollerY.mFinal;
+ }
+
+ /**
+ * Returns how long the scroll event will take, in milliseconds.
+ *
+ * @return The duration of the scroll in milliseconds.
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScrollers don't necessarily have a fixed duration.
+ * This function will lie to the best of its ability.
+ */
+ public final int getDuration() {
+ return Math.max(mScrollerX.mDuration, mScrollerY.mDuration);
+ }
+
+ /**
+ * Extend the scroll animation. This allows a running animation to scroll
+ * further and longer, when used with {@link #setFinalX(int)} or {@link #setFinalY(int)}.
+ *
+ * @param extend Additional time to scroll in milliseconds.
+ * @see #setFinalX(int)
+ * @see #setFinalY(int)
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScrollers don't necessarily have a fixed duration.
+ * Instead of setting a new final position and extending
+ * the duration of an existing scroll, use startScroll
+ * to begin a new animation.
+ */
+ public void extendDuration(int extend) {
+ mScrollerX.extendDuration(extend);
+ mScrollerY.extendDuration(extend);
+ }
+
+ /**
+ * Sets the final position (X) for this scroller.
+ *
+ * @param newX The new X offset as an absolute distance from the origin.
+ * @see #extendDuration(int)
+ * @see #setFinalY(int)
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScroller's final position may change during an animation.
+ * Instead of setting a new final position and extending
+ * the duration of an existing scroll, use startScroll
+ * to begin a new animation.
+ */
+ public void setFinalX(int newX) {
+ mScrollerX.setFinalPosition(newX);
+ }
+
+ /**
+ * Sets the final position (Y) for this scroller.
+ *
+ * @param newY The new Y offset as an absolute distance from the origin.
+ * @see #extendDuration(int)
+ * @see #setFinalX(int)
+ *
+ * @hide Pending removal once nothing depends on it
+ * @deprecated OverScroller's final position may change during an animation.
+ * Instead of setting a new final position and extending
+ * the duration of an existing scroll, use startScroll
+ * to begin a new animation.
+ */
+ public void setFinalY(int newY) {
+ mScrollerY.setFinalPosition(newY);
+ }
+
+ /**
+ * Call this when you want to know the new location. If it returns true, the
+ * animation is not yet finished.
+ */
+ public boolean computeScrollOffset() {
+ if (isFinished()) {
+ return false;
+ }
+
+ switch (mMode) {
+ case SCROLL_MODE:
+ long time = AnimationUtils.currentAnimationTimeMillis();
+ // Any scroller can be used for time, since they were started
+ // together in scroll mode. We use X here.
+ final long elapsedTime = time - mScrollerX.mStartTime;
+
+ final int duration = mScrollerX.mDuration;
+ if (elapsedTime < duration) {
+ float q = (float) (elapsedTime) / duration;
+
+ if (mInterpolator == null)
+ q = Scroller.viscousFluid(q);
+ else
+ q = mInterpolator.getInterpolation(q);
+
+ mScrollerX.updateScroll(q);
+ mScrollerY.updateScroll(q);
+ } else {
+ abortAnimation();
+ }
+ break;
+
+ case FLING_MODE:
+ if (!mScrollerX.mFinished) {
+ if (!mScrollerX.update()) {
+ if (!mScrollerX.continueWhenFinished()) {
+ mScrollerX.finish();
+ }
+ }
+ }
+
+ if (!mScrollerY.mFinished) {
+ if (!mScrollerY.update()) {
+ if (!mScrollerY.continueWhenFinished()) {
+ mScrollerY.finish();
+ }
+ }
+ }
+
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * Start scrolling by providing a starting point and the distance to travel.
+ * The scroll will use the default value of 250 milliseconds for the
+ * duration.
+ *
+ * @param startX Starting horizontal scroll offset in pixels. Positive
+ * numbers will scroll the content to the left.
+ * @param startY Starting vertical scroll offset in pixels. Positive numbers
+ * will scroll the content up.
+ * @param dx Horizontal distance to travel. Positive numbers will scroll the
+ * content to the left.
+ * @param dy Vertical distance to travel. Positive numbers will scroll the
+ * content up.
+ */
+ public void startScroll(int startX, int startY, int dx, int dy) {
+ startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
+ }
+
+ /**
+ * Start scrolling by providing a starting point and the distance to travel.
+ *
+ * @param startX Starting horizontal scroll offset in pixels. Positive
+ * numbers will scroll the content to the left.
+ * @param startY Starting vertical scroll offset in pixels. Positive numbers
+ * will scroll the content up.
+ * @param dx Horizontal distance to travel. Positive numbers will scroll the
+ * content to the left.
+ * @param dy Vertical distance to travel. Positive numbers will scroll the
+ * content up.
+ * @param duration Duration of the scroll in milliseconds.
+ */
+ public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+ mMode = SCROLL_MODE;
+ mScrollerX.startScroll(startX, dx, duration);
+ mScrollerY.startScroll(startY, dy, duration);
}
/**
@@ -91,12 +341,11 @@
mMode = FLING_MODE;
// Make sure both methods are called.
- final boolean spingbackX = mOverScrollerX.springback(startX, minX, maxX);
- final boolean spingbackY = mOverScrollerY.springback(startY, minY, maxY);
+ final boolean spingbackX = mScrollerX.springback(startX, minX, maxX);
+ final boolean spingbackY = mScrollerY.springback(startY, minY, maxY);
return spingbackX || spingbackY;
}
- @Override
public void fling(int startX, int startY, int velocityX, int velocityY,
int minX, int maxX, int minY, int maxY) {
fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, 0, 0);
@@ -105,7 +354,7 @@
/**
* Start scrolling based on a fling gesture. The distance traveled will
* depend on the initial velocity of the fling.
- *
+ *
* @param startX Starting point of the scroll (X)
* @param startY Starting point of the scroll (Y)
* @param velocityX Initial velocity of the fling (X) measured in pixels per
@@ -132,43 +381,87 @@
public void fling(int startX, int startY, int velocityX, int velocityY,
int minX, int maxX, int minY, int maxY, int overX, int overY) {
mMode = FLING_MODE;
- mOverScrollerX.fling(startX, velocityX, minX, maxX, overX);
- mOverScrollerY.fling(startY, velocityY, minY, maxY, overY);
+ mScrollerX.fling(startX, velocityX, minX, maxX, overX);
+ mScrollerY.fling(startY, velocityY, minY, maxY, overY);
}
- void notifyHorizontalBoundaryReached(int startX, int finalX) {
- mOverScrollerX.springback(startX, finalX, finalX);
+ /**
+ * Notify the scroller that we've reached a horizontal boundary.
+ * Normally the information to handle this will already be known
+ * when the animation is started, such as in a call to one of the
+ * fling functions. However there are cases where this cannot be known
+ * in advance. This function will transition the current motion and
+ * animate from startX to finalX as appropriate.
+ *
+ * @param startX Starting/current X position
+ * @param finalX Desired final X position
+ * @param overX Magnitude of overscroll allowed. This should be the maximum
+ * desired distance from finalX. Absolute value - must be positive.
+ */
+ public void notifyHorizontalEdgeReached(int startX, int finalX, int overX) {
+ mScrollerX.notifyEdgeReached(startX, finalX, overX);
}
- void notifyVerticalBoundaryReached(int startY, int finalY) {
- mOverScrollerY.springback(startY, finalY, finalY);
- }
-
- void notifyHorizontalEdgeReached(int startX, int finalX, int overX) {
- mOverScrollerX.notifyEdgeReached(startX, finalX, overX);
- }
-
- void notifyVerticalEdgeReached(int startY, int finalY, int overY) {
- mOverScrollerY.notifyEdgeReached(startY, finalY, overY);
+ /**
+ * Notify the scroller that we've reached a vertical boundary.
+ * Normally the information to handle this will already be known
+ * when the animation is started, such as in a call to one of the
+ * fling functions. However there are cases where this cannot be known
+ * in advance. This function will animate a parabolic motion from
+ * startY to finalY.
+ *
+ * @param startY Starting/current Y position
+ * @param finalY Desired final Y position
+ * @param overY Magnitude of overscroll allowed. This should be the maximum
+ * desired distance from finalY.
+ */
+ public void notifyVerticalEdgeReached(int startY, int finalY, int overY) {
+ mScrollerY.notifyEdgeReached(startY, finalY, overY);
}
/**
* Returns whether the current Scroller is currently returning to a valid position.
* Valid bounds were provided by the
* {@link #fling(int, int, int, int, int, int, int, int, int, int)} method.
- *
+ *
* One should check this value before calling
- * {@link startScroll(int, int, int, int)} as the interpolation currently in progress to restore
- * a valid position will then be stopped. The caller has to take into account the fact that the
- * started scroll will start from an overscrolled position.
+ * {@link #startScroll(int, int, int, int)} as the interpolation currently in progress
+ * to restore a valid position will then be stopped. The caller has to take into account
+ * the fact that the started scroll will start from an overscrolled position.
*
- * @return true when the current position is overscrolled and interpolated back to a valid value.
+ * @return true when the current position is overscrolled and in the process of
+ * interpolating back to a valid value.
*/
public boolean isOverscrolled() {
- return ((!mOverScrollerX.mFinished &&
- mOverScrollerX.mState != MagneticOverScroller.TO_EDGE) ||
- (!mOverScrollerY.mFinished &&
- mOverScrollerY.mState != MagneticOverScroller.TO_EDGE));
+ return ((!mScrollerX.mFinished &&
+ mScrollerX.mState != MagneticOverScroller.TO_EDGE) ||
+ (!mScrollerY.mFinished &&
+ mScrollerY.mState != MagneticOverScroller.TO_EDGE));
+ }
+
+ /**
+ * Stops the animation. Contrary to {@link #forceFinished(boolean)},
+ * aborting the animating causes the scroller to move to the final x and y
+ * positions.
+ *
+ * @see #forceFinished(boolean)
+ */
+ public void abortAnimation() {
+ mScrollerX.finish();
+ mScrollerY.finish();
+ }
+
+ /**
+ * Returns the time elapsed since the beginning of the scrolling.
+ *
+ * @return The elapsed time in milliseconds.
+ *
+ * @hide
+ */
+ public int timePassed() {
+ final long time = AnimationUtils.currentAnimationTimeMillis();
+ final long startTime = Math.min(mScrollerX.mStartTime, mScrollerY.mStartTime);
+ return (int) (time - startTime);
}
static class MagneticOverScroller extends Scroller.MagneticScroller {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 36d244f..23e1234 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -963,7 +963,6 @@
dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;
mScroller.startScroll(mScrollX, scrollY, 0, dy);
- awakenScrollBars(mScroller.getDuration());
invalidate();
} else {
if (!mScroller.isFinished()) {
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 6a2f000..abb3e32 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -32,16 +32,16 @@
* computeScrollOffset() will always return false to indicate that scrolling is over.
*/
public class Scroller {
- int mMode;
+ private int mMode;
- MagneticScroller mScrollerX;
- MagneticScroller mScrollerY;
+ private MagneticScroller mScrollerX;
+ private MagneticScroller mScrollerY;
private final Interpolator mInterpolator;
- static final int DEFAULT_DURATION = 250;
- static final int SCROLL_MODE = 0;
- static final int FLING_MODE = 1;
+ private static final int DEFAULT_DURATION = 250;
+ private static final int SCROLL_MODE = 0;
+ private static final int FLING_MODE = 1;
// This controls the viscous fluid effect (how much of it)
private final static float VISCOUS_FLUID_SCALE = 8.0f;
@@ -65,16 +65,12 @@
* null, the default (viscous) interpolator will be used.
*/
public Scroller(Context context, Interpolator interpolator) {
- instantiateScrollers();
+ mScrollerX = new MagneticScroller();
+ mScrollerY = new MagneticScroller();
MagneticScroller.initializeFromContext(context);
mInterpolator = interpolator;
}
-
- void instantiateScrollers() {
- mScrollerX = new MagneticScroller();
- mScrollerY = new MagneticScroller();
- }
/**
*
@@ -289,7 +285,7 @@
mScrollerY.fling(startY, velocityY, minY, maxY);
}
- private static float viscousFluid(float x) {
+ static float viscousFluid(float x) {
x *= VISCOUS_FLUID_SCALE;
if (x < 1.0f) {
x -= (1.0f - (float)Math.exp(-x));