- Scroller. Android基础位移计算应用类,短小精悍,被动式模拟计算位移过程。
- 注释里对Scroller的定位说的很清楚:该类封装了Scrolling操作,在你需要进行scroll动画的时候可以用Scroller/OverScroller来收集和产出相关的信息,Scroller会为你跟踪随着时间产生的scroll offset及新的坐标, 但是,它不会自动的把这些变化替你apply到相应的View上,调用者自己来获取并且将新的坐标apply到相应的View上, 并且这个操作的频率也由你自己来把握,以使得scroll动画看起来是流畅平滑的
- 在使用过程中,为了跟踪X/Y坐标的变化(得到当前这个时间最新的x/y坐标),需要自己调用computeScrollOffset(…), 这个函数将返回true/false来表明Scroller此次的Scroll是否已经结束了
- Scroller的构造函数最多接受三个参数:
- Context:
- Interpolator: 有默认值
- boolean flywheel:
- mPpi = ontext.getResources().getDisplayMetrics().density * 160.0f
- mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction())
- mFinished初始化为true.
- startScroll(int startX, int startY, int dx, int dy, int duration):
- 开始一次**模拟**Scroll过程的计算
- duration如果不指定,那么有一个默认的时间DEFAULT_DURATION
- mMode = SCROLL_MODE
- mFinished = false;
- mStartTime = AnimationUtils.currentAnimationTimeMillis(); 其实调的还是SystemClock.uptimeMillis()
- 根据startX/Y, dx/y 来设定mStartX/Y, mFinalX/Y, mDeltaX/Y
- mDurationReciprocal = 1.0f / (float) mDuration; 倒数
- fling(int startX, int startY, int velocityX, int velocityY,
int minX, int maxX, int minY, int maxY):
- 开始一次**模拟**Fling过程的计算
- 如果允许mFlywheel并且当前的模拟位移过程还没有结束,那么会继续一次scroll/fling
- mMode = FLING_MODE
- Fling对速度的相对复杂,暂不细表.
- computeScrollOffset():
- 最开始已经说了它的重要地位,严格来讲,Scroller是不会自动的替你模拟位移过程的,只有你一次次主动的调用computeScrollOffset(),才会推动Scroller不断的基于当前时间算出一系列的位移信息
- Scroller是被动式的
- 如果mFinsihed, 直接返回false**代表着这一次的模拟位移过程已经结束**
- 基于mStartTime获取本次模拟位移过程已经过去的时间.
- 如果过去的时间已经大于了模拟过程指定的duration, 渐变计算已经没有意义,那么直接将mCurrX/Y设置为mFinalX/Y. mFinished = true
- 如果还在duration内,根据mode进行不同处理:
- SCROLL_MODE:
- timePassed * mDurationReciprocal 获得时间流逝的百分比
- 如果没有指定Interpolator,那么使用viscousFluid函数来对流逝百分比进行重计算.
- 否则就用给定的Interpolator进行流逝百分比重计算(为了实现加速减速等效果)
- 根据流逝百分比计算出位移过程中此刻当前X/Y的值:mCurrX/Y = mStartX/Y + Math.round(x/y * mDeltaX/Y(代表X/Y总的位移量));
- FLING_MODE:
- fling的模拟计算没有用到Interpolator,因为也确实用不了
- 计算流程暂不细表,但是最终算出的也就是mCurX/Y这两个值
- 最后根据比较mCurrX/Y和mFinalX/Y, 如果想等,那么mFinished = true.
- forceFinished(boolean finished)和abortAnimation() 两者的不同在与:
- forceFinished(boolean finished)只会改变mFinished的值,这意味者如果位移模拟过程正在进行中,调用了forceFinished(true), 那么mCurX/Y会停留在当前的值
- abortAnimation()则会直接将mCurX/Y设置为mFinalX/Y, 可以理解为直接将模拟过程快进到了结束状态
- extendDuration(int extend):
- 可以增加当前模拟过程的持续时间,即使这个模拟过程已经开始了或者已经结束了
- 会将mFinished设为false.
- mDuration和mDurationReciprocal都会重新计算,但是要配合setFinalX/Y(int)使用,否则很容易出现问题
- setFinalX/Y(int newX/Y):
- 重新设定一个FinalX/Y, 重置mDeltaX和mFinished
- Math.sigNum(…)比较有意思,适合对数字做归一化, 在这里则被用做方向的判定(根据移动距离的正负进行sigNum归一化为 -1, 0, 1, 从而方便比较)