/** * 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 second. * @param velocityY Initial velocity of the fling (Y) measured in pixels per second * @param minX Minimum X value. The scroller will not scroll past this point unless overX > 0. If * overfling is allowed, it will use minX as a springback boundary. * @param maxX Maximum X value. The scroller will not scroll past this point unless overX > 0. If * overfling is allowed, it will use maxX as a springback boundary. * @param minY Minimum Y value. The scroller will not scroll past this point unless overY > 0. If * overfling is allowed, it will use minY as a springback boundary. * @param maxY Maximum Y value. The scroller will not scroll past this point unless overY > 0. If * overfling is allowed, it will use maxY as a springback boundary. * @param overX Overfling range. If > 0, horizontal overfling in either direction will be * possible. * @param overY Overfling range. If > 0, vertical overfling in either direction will be possible. */ public void fling( int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY, int overX, int overY, long time) { // Continue a scroll or fling in progress if (mFlywheel && !isFinished()) { float oldVelocityX = mScrollerX.mCurrVelocity; float oldVelocityY = mScrollerY.mCurrVelocity; boolean sameXDirection = (velocityX == 0) || (oldVelocityX == 0) || ((velocityX < 0) == (oldVelocityX < 0)); boolean sameYDirection = (velocityY == 0) || (oldVelocityY == 0) || ((velocityY < 0) == (oldVelocityY < 0)); if (sameXDirection) { velocityX += oldVelocityX; } if (sameYDirection) { velocityY += oldVelocityY; } } mMode = FLING_MODE; mScrollerX.fling(startX, velocityX, minX, maxX, overX, time); mScrollerY.fling(startY, velocityY, minY, maxY, overY, time); }
/** * Call this when you want to 'spring back' into a valid coordinate range. * * @param startX Starting X coordinate * @param startY Starting Y coordinate * @param minX Minimum valid X value * @param maxX Maximum valid X value * @param minY Minimum valid Y value * @param maxY Minimum valid Y value * @return true if a springback was initiated, false if startX and startY were already within the * valid range. */ public boolean springBack( int startX, int startY, int minX, int maxX, int minY, int maxY, long time) { mMode = FLING_MODE; // Make sure both methods are called. final boolean spingbackX = mScrollerX.springback(startX, minX, maxX, time); final boolean spingbackY = mScrollerY.springback(startY, minY, maxY, time); return spingbackX || spingbackY; }
/** * Call this when you want to know the new location. If it returns true, the animation is not yet * finished. */ public boolean computeScrollOffset(long time) { if (isFinished()) { return false; } switch (mMode) { case SCROLL_MODE: // 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; q = viscousFluid(q); mScrollerX.updateScroll(q); mScrollerY.updateScroll(q); } else { abortAnimation(); } break; case FLING_MODE: if (!mScrollerX.mFinished) { if (!mScrollerX.update(time)) { if (!mScrollerX.continueWhenFinished(time)) { mScrollerX.finish(); } } } if (!mScrollerY.mFinished) { if (!mScrollerY.update(time)) { if (!mScrollerY.continueWhenFinished(time)) { mScrollerY.finish(); } } } break; default: break; } return true; }
/** * 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; }
/** * 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(); }
/** * 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, long startTime, int duration) { mMode = SCROLL_MODE; mScrollerX.startScroll(startX, dx, startTime, duration); mScrollerY.startScroll(startY, dy, startTime, duration); }
/** * Sets where the scroll will end. Valid only for "fling" scrolls. * * @param x The final X offset as an absolute distance from the origin. */ public final void setFinalX(int x) { mScrollerX.setFinalPosition(x); }