上篇說到,可以使用scrollBy和scrollTo移動View,這裡產生一個問題,加入一個View在螢幕的左上方即(0,0)位置,他調用
scrollTo(-300,-300)時,會立即跳過去,顯得很突兀,如何讓他平緩地划過去呢?就可以用本篇的方法了。
使用方法:
int startX;//滑動動作的起始點x座標
int startY;//滑動動作的起始點y座標
int dx; //x軸位移量向左為負,向右為正(即負值向右移,正值向左移)
int dy; //y軸位移量向左為負,向右為正(即負值向右移,正值向左移)
int duration;//時間,預設為250ms
注意:這裡的dx和dy和上篇的scrollBy的參數相似,都是往哪個地方移動了多少,而不是往哪個點移動
Scroller mScroller=new Scroller(context);
mScroller.startScroll(startX,startY,dx,dy);
invalidate();//
除了上面的代碼之外,還得重寫View的computeScroll方法:
這裡我的理解是:判斷某一階段滑動完成,就調用scrollTo方法,實現真正的移動
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
super.computeScroll();
}
可能大家還有點不明白,我還是來畫圖吧:
一個view,距離上邊300px,距離左邊300px,即他的座標為(300,300);
那麼這個時候,我們希望他從當前的這個位置,緩慢移動到(0,0),用時1秒,就這麼寫:
mScroller.startScroll(-300, -300, 300, 300,1000);
假設我們希望它從(300,300)移動到(100,100):
mScroller.startScroll(-300, -300, 200, 200,5000);
假設我們希望它從(300,300)移動到(200,200):
mScroller.startScroll(-300, -300, 100, 100,5000);
這樣只是移動某段距離,那我們怎麼樣使它移動到一個固定的點呢?
我們可以這樣做:假設我們想要移動到(100,100):
mScroller.startScroll(-300, -300, 0, 0, 500);
mScroller.setFinalX(100);
mScroller.setFinalY(100);
invalidate();
我為什麼這樣寫呢?是有依據的,看一下startScroll的源碼:
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
mMode = SCROLL_MODE;
mFinished = false;
mDuration = duration;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mStartX = startX;
mStartY = startY;
mFinalX = startX + dx;
mFinalY = startY + dy;
mDeltaX = dx;
mDeltaY = dy;
mDurationReciprocal = 1.0f / (float) mDuration;
}
其中:
mFinalX = startX + dx;
mFinalY = startY + dy;
就是把我們傳進去的幾個值加了一下,意思就是,我們傳的dx,dy,就是我們移動的位移量,受到起始數值的約束,
所以我們單獨操控mFinalX、mFinalY就可以了.
最後解釋一下computeScroll方法:
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
super.computeScroll();
}
首先把上面的例子拿來:
mScroller.startScroll(-300, -300, 300, 300,1000);
在(300,300)點,用時一秒,移動到(0,0),我們想一下,在一秒內完成這個操作,假設我們細分成100部分,即一部分為10ms,
那麼在第一個10ms, mScrollerd的getCurrX()就是-300+3=-270,getCurrX同理,即第一個10ms後,view需要向左邊移動了3px,這個時候computeScroll調用了,我們先判斷一下mScroller的第一個階段是不是完成了,假設完成了,就調用scrollTo()方法。
這樣經過100個部分,在我們看來,就是緩慢的移動過去了.