Scroller封裝了滑動過程锌畸,當你需要實現(xiàn)一個滑動動畫的時候勇劣,可以使用Scroller或是OverScroller類采集數(shù)據(jù)。例如潭枣,為了處理fling手勢比默,隨著時間的推移,Scrollers記錄著滑動的偏移量盆犁,但是Scroller不會主動向View上報它的坐標命咐。開發(fā)者需要以一定的頻率主動向Scroller獲取坐標,這樣才能保證實現(xiàn)平滑滑動動畫谐岁。
例如:
private Scroller mScroller = new Scroller(context);//實例化一個Scroller對象
public void zoomIn(){
mScroller.forceFinished(true);//強制停止Scroller滑動
mScroller.startScroll(0, 0, 100, 0);//此方法只是啟動開始滑動的位置醋奠,實際并沒有執(zhí)行滑動過程
invalidate();//invalidate會導致View重繪
}
使用computeScrollOffset()方法,跟蹤x/y坐標的變化伊佃。computeScrollOffset()方法返回一個布爾值窜司,來標識滑動是不是已經(jīng)停止。如果沒有停止锭魔,則意味著fling動作還在執(zhí)行中例证。如果滑動沒有停止路呜,則返回true,如果滑動已經(jīng)停止迷捧,則返回false织咧。可以使用Scroller.getCurrX()和Scroller.getCurrY()方法來獲取當前x/y坐標的偏移量漠秋。
例如:
if (mScroller.computeScrollOffset()){
int currX = mScroller.getCurrX();
int currY = mScroller.getCurrY();
}
computeScrollOffset()函數(shù)詳解:
當需要獲取滑動過程中新的坐標值時笙蒙,調用此方法,如果此方法返回true庆锦,則說明滑動過程尚未停止
public boolean computeScrollOffset() {
if (mFinished) {//如果滑動已經(jīng)停止捅位,則直接返回false
return false;
}
int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);//獲取從開始滑動到現(xiàn)在經(jīng)過了多長時間
if (timePassed < mDuration) {//如果滑動的時間小于startScroll()函數(shù)設置的滑動時間
switch (mMode) {//根據(jù)滑動的不同類型,得到此時當前坐標的值
case SCROLL_MODE:
final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
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 {//執(zhí)行滑動的時間已經(jīng)不小于startScroll()函數(shù)設置的滑動時間小搂抒,說明滑動已經(jīng)停止
mCurrX = mFinalX;//把當前坐標設置為startScroll()函數(shù)設置的滑動最終位置的坐標
mCurrY = mFinalY;
mFinished = true;
}
return true;
}