OverScrollerpublic class OverScroller extends Object This class encapsulates scrolling with the ability to overshoot the bounds
of a scrolling operation. This class is a drop-in replacement for
{@link android.widget.Scroller} in most cases. |
Fields Summary |
---|
private int | mMode | private final SplineOverScroller | mScrollerX | private final SplineOverScroller | mScrollerY | private android.view.animation.Interpolator | mInterpolator | private final boolean | mFlywheel | private static final int | DEFAULT_DURATION | private static final int | SCROLL_MODE | private static final int | FLING_MODE |
Constructors Summary |
---|
public OverScroller(android.content.Context context)Creates an OverScroller with a viscous fluid scroll interpolator and flywheel.
this(context, null);
| public OverScroller(android.content.Context context, android.view.animation.Interpolator interpolator)Creates an OverScroller with flywheel enabled.
this(context, interpolator, true);
| public OverScroller(android.content.Context context, android.view.animation.Interpolator interpolator, boolean flywheel)Creates an OverScroller.
if (interpolator == null) {
mInterpolator = new Scroller.ViscousFluidInterpolator();
} else {
mInterpolator = interpolator;
}
mFlywheel = flywheel;
mScrollerX = new SplineOverScroller(context);
mScrollerY = new SplineOverScroller(context);
| public OverScroller(android.content.Context context, android.view.animation.Interpolator interpolator, float bounceCoefficientX, float bounceCoefficientY)Creates an OverScroller with flywheel enabled.
this(context, interpolator, true);
| public OverScroller(android.content.Context context, android.view.animation.Interpolator interpolator, float bounceCoefficientX, float bounceCoefficientY, boolean flywheel)Creates an OverScroller.
this(context, interpolator, flywheel);
|
Methods Summary |
---|
public void | abortAnimation()Stops the animation. Contrary to {@link #forceFinished(boolean)},
aborting the animating causes the scroller to move to the final x and y
positions.
mScrollerX.finish();
mScrollerY.finish();
| public boolean | computeScrollOffset()Call this when you want to know the new location. If it returns true, the
animation is not yet finished.
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) {
final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
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;
| public void | extendDuration(int extend)Extend the scroll animation. This allows a running animation to scroll
further and longer, when used with {@link #setFinalX(int)} or {@link #setFinalY(int)}.
mScrollerX.extendDuration(extend);
mScrollerY.extendDuration(extend);
| 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);
| public void | fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY, int overX, int overY)Start scrolling based on a fling gesture. The distance traveled will
depend on the initial velocity of the fling.
// Continue a scroll or fling in progress
if (mFlywheel && !isFinished()) {
float oldVelocityX = mScrollerX.mCurrVelocity;
float oldVelocityY = mScrollerY.mCurrVelocity;
if (Math.signum(velocityX) == Math.signum(oldVelocityX) &&
Math.signum(velocityY) == Math.signum(oldVelocityY)) {
velocityX += oldVelocityX;
velocityY += oldVelocityY;
}
}
mMode = FLING_MODE;
mScrollerX.fling(startX, velocityX, minX, maxX, overX);
mScrollerY.fling(startY, velocityY, minY, maxY, overY);
| public final void | forceFinished(boolean finished)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.
mScrollerX.mFinished = mScrollerY.mFinished = finished;
| public float | getCurrVelocity()Returns the absolute value of the current velocity.
float squaredNorm = mScrollerX.mCurrVelocity * mScrollerX.mCurrVelocity;
squaredNorm += mScrollerY.mCurrVelocity * mScrollerY.mCurrVelocity;
return FloatMath.sqrt(squaredNorm);
| public final int | getCurrX()Returns the current X offset in the scroll.
return mScrollerX.mCurrentPosition;
| public final int | getCurrY()Returns the current Y offset in the scroll.
return mScrollerY.mCurrentPosition;
| public final int | getDuration()Returns how long the scroll event will take, in milliseconds.
return Math.max(mScrollerX.mDuration, mScrollerY.mDuration);
| public final int | getFinalX()Returns where the scroll will end. Valid only for "fling" scrolls.
return mScrollerX.mFinal;
| public final int | getFinalY()Returns where the scroll will end. Valid only for "fling" scrolls.
return mScrollerY.mFinal;
| public final int | getStartX()Returns the start X offset in the scroll.
return mScrollerX.mStart;
| public final int | getStartY()Returns the start Y offset in the scroll.
return mScrollerY.mStart;
| public final boolean | isFinished()Returns whether the scroller has finished scrolling.
return mScrollerX.mFinished && mScrollerY.mFinished;
| public boolean | isOverScrolled()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.
return ((!mScrollerX.mFinished &&
mScrollerX.mState != SplineOverScroller.SPLINE) ||
(!mScrollerY.mFinished &&
mScrollerY.mState != SplineOverScroller.SPLINE));
| public boolean | isScrollingInDirection(float xvel, float yvel)
final int dx = mScrollerX.mFinal - mScrollerX.mStart;
final int dy = mScrollerY.mFinal - mScrollerY.mStart;
return !isFinished() && Math.signum(xvel) == Math.signum(dx) &&
Math.signum(yvel) == Math.signum(dy);
| public void | notifyHorizontalEdgeReached(int startX, int finalX, int overX)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.
mScrollerX.notifyEdgeReached(startX, finalX, overX);
| public void | notifyVerticalEdgeReached(int startY, int finalY, int 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.
mScrollerY.notifyEdgeReached(startY, finalY, overY);
| public void | setFinalX(int newX)Sets the final position (X) for this scroller.
mScrollerX.setFinalPosition(newX);
| public void | setFinalY(int newY)Sets the final position (Y) for this scroller.
mScrollerY.setFinalPosition(newY);
| public final void | setFriction(float friction)The amount of friction applied to flings. The default value
is {@link ViewConfiguration#getScrollFriction}.
mScrollerX.setFriction(friction);
mScrollerY.setFriction(friction);
| void | setInterpolator(android.view.animation.Interpolator interpolator)
if (interpolator == null) {
mInterpolator = new Scroller.ViscousFluidInterpolator();
} else {
mInterpolator = interpolator;
}
| public boolean | springBack(int startX, int startY, int minX, int maxX, int minY, int maxY)Call this when you want to 'spring back' into a valid coordinate range.
mMode = FLING_MODE;
// Make sure both methods are called.
final boolean spingbackX = mScrollerX.springback(startX, minX, maxX);
final boolean spingbackY = mScrollerY.springback(startY, minY, maxY);
return spingbackX || spingbackY;
| public void | startScroll(int startX, int startY, int dx, int dy)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.
startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
| public void | startScroll(int startX, int startY, int dx, int dy, int duration)Start scrolling by providing a starting point and the distance to travel.
mMode = SCROLL_MODE;
mScrollerX.startScroll(startX, dx, duration);
mScrollerY.startScroll(startY, dy, duration);
| public int | timePassed()Returns the time elapsed since the beginning of the scrolling.
final long time = AnimationUtils.currentAnimationTimeMillis();
final long startTime = Math.min(mScrollerX.mStartTime, mScrollerY.mStartTime);
return (int) (time - startTime);
|
|