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