scrollerjava
Scroller scroller = new Scroller(getApplicationContext()); scroller.startScroll(0, 0, 100, 100, 500); while (!scroller.isFinished()) { Log.d("scroller", scroller.getCurrX() + " " + scroller.getCurrY()); scroller.computeScrollOffset(); }
scroller :app
private class Flinger implements Runnable { private final Scroller scroller; private int lastX = 0; Flinger() { scroller = new Scroller(getActivity()); } void start(int initialVelocity) { int initialX = scrollingView.getScrollX(); int maxX = Integer.MAX_VALUE; // or some appropriate max value in your code scroller.fling(initialX, 0, initialVelocity, 0, 0, maxX, 0, 10); Log.i(TAG, "starting fling at " + initialX + ", velocity is " + initialVelocity + ""); lastX = initialX; getView().post(this); } public void run() { if (scroller.isFinished()) { Log.i(TAG, "scroller is finished, done with fling"); return; } boolean more = scroller.computeScrollOffset(); int x = scroller.getCurrX(); int diff = lastX - x; if (diff != 0) { scrollingView.scrollBy(diff, 0); lastX = x; } if (more) { getView().post(this); } } boolean isFlinging() { return !scroller.isFinished(); } void forceFinished() { if (!scroller.isFinished()) { scroller.forceFinished(true); } }}
每次想知道當前的滑動距離時須要調用computeScrollOffset, 它根據當前的流逝時間及以前設置的參數(起始點、速度等)來計算當前應有的滑動距離,或者當前的位置。post
/** * Call this when you want to know the new location. If it returns true, * the animation is not yet finished. */ public boolean computeScrollOffset() { if (mFinished) { return false; } int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime); if (timePassed < mDuration) { switch (mMode) { case SCROLL_MODE: float x = timePassed * mDurationReciprocal; if (mInterpolator == null) x = viscousFluid(x); else x = mInterpolator.getInterpolation(x); mCurrX = mStartX + Math.round(x * mDeltaX); mCurrY = mStartY + Math.round(x * mDeltaY); break; case FLING_MODE: final float t = (float) timePassed / mDuration; final int index = (int) (NB_SAMPLES * t); float distanceCoef = 1.f; float velocityCoef = 0.f; if (index < NB_SAMPLES) { final float t_inf = (float) index / NB_SAMPLES; final float t_sup = (float) (index + 1) / NB_SAMPLES; final float d_inf = SPLINE_POSITION[index]; final float d_sup = SPLINE_POSITION[index + 1]; velocityCoef = (d_sup - d_inf) / (t_sup - t_inf); distanceCoef = d_inf + (t - t_inf) * velocityCoef; } mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f; mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX)); // Pin to mMinX <= mCurrX <= mMaxX mCurrX = Math.min(mCurrX, mMaxX); mCurrX = Math.max(mCurrX, mMinX); mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY)); // Pin to mMinY <= mCurrY <= mMaxY mCurrY = Math.min(mCurrY, mMaxY); mCurrY = Math.max(mCurrY, mMinY); if (mCurrX == mFinalX && mCurrY == mFinalY) { mFinished = true; } break; } } else { mCurrX = mFinalX; mCurrY = mFinalY; mFinished = true; } return true; }