Scroller源码解析

1.构造方法

public Scroller(Context context) {
    this(context, null);
}

public Scroller(Context context, Interpolator interpolator) {
    this(context, interpolator,
            context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB);
}

public Scroller(Context context, Interpolator interpolator, boolean flywheel) {
    mFinished = true;
    if (interpolator == null) {
        mInterpolator = new ViscousFluidInterpolator();
    } else {
        mInterpolator = interpolator;
    }
    mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
    mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
    mFlywheel = flywheel;

    mPhysicalCoeff = computeDeceleration(0.84f); 
}

从上面代码可以看到有三个构造方法,默认通过一个参数的构造方法调两个参数的构造方法,再通过两个参数的构造方法调三个参数的构造方法.通常情况下我们都是用的第一个构造方法,第二个构造函数需要传进去一个插值器Interpolator.如果不传则采用默认的的插值器ViscousFluidInterpolator.

2.startScroll()方法

public void startScroll(int startX, int startY, int dx, int dy) {
    startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
}
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;
}

通过第一个方法调第二方法,调第一个方法没有传入持续时间则默认为250.在startScroll()方法中并没有调用类似开启滑动的方法,而是保存了传进来的各种参数:startX,startY表示滑动的开始点,dx,dy表示滑动的距离,duration则表示滑动持续的时间.所以startScroll()方法只是用来做前期准备活动的,并不能使View进行滑动.关键是我们在startScroll()方法后调用了invalidate()方法,这个方法会导致View重绘,而View的重绘会调用View的draw()方法,draw()方法又会调用computeScroll()方法.我们重写computeScroll()方法如下:

public void computeScroll() {
    super.computeScroll();
    if (mScroller.computeScrollOffset()){
        ((View)getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
        invalidate();
    }
}

你可能感兴趣的:(Scroller源码解析)