Scroller弹性滑动原理

Scroller的典型使用方法:

Scroller mScroller = new Scroller(mContext);

private void smoothScrollTo(int destX, int destY) {
    int scrollX = getScrollX()int scrollY = getScrollY();
    int deltaX = destX - scrollX;
    int deltaY = destY - scrollY;
    mScroller.startScroll(scrollX, scrollY, deltaX, deltaY, 1000);
    invalidate();
}


@Override
public void computeScroll() {
    if(mScrolller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
    }
}

先分析startScroll方法,此方法就只讲Scroller中的属性赋值。

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;
    }

当调用invalidate()方法时,回导致View重绘,在View的draw方法中又会调用computeScroll()方法,在实现的computeScroll方法会调用mScrolller.computeScrollOffset()方法,接下来看computeScrollOffset()方法:

public boolean computeScrollOffset() {
    ...
        int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
    
        if (timePassed < mDuration) {
            switch (mMode) {
            case SCROLL_MODE:
                final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
                mCurrX = mStartX + Math.round(x * mDeltaX);
                mCurrY = mStartY + Math.round(x * mDeltaY);
                break;
      ...
        }
        return true;
}

从上述方法就可以计算出如下数据:

mCurrX = mStartX + Math.round(x * mDeltaX);
mCurrY = mStartY + Math.round(x * mDeltaY);

此处就可以通过scrollTo(mScroller.getCurrX(), mScroller.getCurrY());来对view进行滑动。

发布了13 篇原创文章 · 获赞 2 · 访问量 576

猜你喜欢

转载自blog.csdn.net/qq_42806685/article/details/104409578