彈性滑動
在看Scroller的使用方法之前我們需要先了解一下View的scrollTo和scrollTo方法,
public void scrollTo(int x,int y){
//如果當前偏移量變化
if(mScrollX!=x||mScrollY!=y){
int oldX=mScrollX;
int oldY=mScrollY();
//賦值偏移量
mScrollX=x;
mScrollY=y;
invalidateParentCaches();
//回調onScrollChanged方法
onScrollChanged(mScrollX,mScrollY,oldX,oldY);
if(!awakenScrollBars()){
postInvalidateOnAnimation();
}
}
}
scrollTo()是指將前視圖內容橫向偏移x距離,縱向偏移y距離。注意這里是View的內容的偏移,而不是View本身。而scrollBy()方法如下:
public void scrollBy(int x,int y){
scrollTo(mScrollX+x,mScrollY+y);
}
scrollBy()方法里直接調用了scrollTo()方法,表示在當前偏移量的基礎上繼續偏移(x,y)。
使用Scroller開始
Scroller scroller=new Scroller(mContext);
//緩慢滾動到指定位置
private void smoothScrollTo(int destX,int destY){
int scrollX=getScrollX();
int deltaX=destX-scrollX;
//1000ms內滑動destX,效果就是慢慢移動
mScroller.startScroll(scrollX,0,detaX,0,1000);\
//invalidate方法會導致View的重繪,在View的draw方法中又會去調用computeScroll方法
//invalidate-draw-computeScroll
invalidate();
}
@Override
public void computeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
//view第二次重繪
postInvalidate();
}
}
上面是Scroller典型的使用方法,當我們構造一個Scroller對象時并且調用它的startScroll方法時,Scroller內部其實什么也不做,它只是保存了我們傳入的幾個參數,這幾個參數從startScroll的原型上就可以看出來
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// mMode 分兩種方式 1.滑動:SCROLL_MODE 2. **加速度滑動:FLING_MODE**
mMode = SCROLL_MODE;
// 是否滑動結束 這里是開始所以設置為false
mFinished = false;
// 滑動的時間
mDuration = duration;
// 開始的時間
mStartTime = AnimationUtils.currentAnimationTimeMillis();
// 開始滑動點的X坐標
mStartX = startX;
// 開始滑動點的Y坐標
mStartY = startY;
// 最終滑動到位置的X坐標
mFinalX = startX + dx;
// 最終滑動到位置的Y坐標
mFinalY = startY + dy;
// X方向上滑動的偏移量
mDeltaX = dx;
// Y方向上滑動的偏移量
mDeltaY = dy;
// 持續時間的倒數 最終用來計算得到插值器返回的值
mDurationReciprocal = 1.0f / (float) mDuration;
}
1.startScroll(int startX, int startY, int dx, int dy, int duration):
通過起始點、偏移的距離和滑動的時間來開始滑動。
- startX 起始滑動點的X坐標
- startY 起始滑動點的Y坐標
- dx 滑動的水平偏移量。>0 則表示往左滑動。
- dy 滑動的垂直偏移量。>0 則表示往上滑動。
- duration 滑動執行的時間
startX和startY表示的是滑動的起點,dx與dy表示的是滑動的距離,而duration表示的是滑動的時間,即整個滑動過程完成所需要的時間,這里的滑動是指View的內容(content)的滑動,而非View本身位置的滑動。