OverScroller

OverScroller 是 Scroller 的加强版,增加了滚出视图范围之后的回弹效果,但这个效果最好还是别用了。

OverScroller 是一个辅助类,用来实现视图的平滑滚动。
说道平滑,实质就是利用系统重画的间隔,16ms(实际值),不断重新计算值并重画。无论是使用 ValueAnimator ,还是 OverScroller ,本质都是一样的。

平滑滚动

GIF.gif

滚动的实质是移动了画布的原点,所以视图本身的坐标和大小都没发生变化,依旧能触发点击事件。

public class CustomLinearLayout extends LinearLayout {   
 
   // ... constructor

  OverScroller scroller = new OverScroller(getContext());    
  public void smoothScroll() {      
    int increment = 200;
    int duration = 300;     
    scroller.startScroll(0, getScrollY(), 0, increment, duration);      
    invalidate(); 
  }
  
  @Override   
  public void computeScroll() {        
    if (scroller.computeScrollOffset()) {       
     scrollTo(0, scroller.getCurrY());     
    }   
   }
  }
case SCROLL_MODE:   
// 这个时间是不可修改的
long time = AnimationUtils.currentAnimationTimeMillis();    
final long elapsedTime = time - mScrollerX.mStartTime;    
final int duration = mScrollerX.mDuration;    
if (elapsedTime < duration) {
  // 根据过去的时间计算滚动距离,线性插值器就是 Y=X,其他差值器也会经过(0,0) 和(1,1),变的只是趋势。
  // q 是一个 0~1 的值。
  final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
  mScrollerX.updateScroll(q);
  mScrollerY.updateScroll(q);    
} else {
  abortAnimation();
}
break;
void updateScroll(float q) {
  // 计算时使用的是 float ,精度高;最后的值是 int,因为像素是最小单位。
  mCurrentPosition = mStart + Math.round(q * (mFinal - mStart));
}

fling

OverScroller 的另一个功能就是 fling。
平滑滚动是以过去时间到达 duration 作为滚动结束条件的。
fling 则是捕捉一个 fling 事件,获取出初始速度(模拟滑动的惯性),然后设置一定的阻力,计算出速度消减为 0 所需的时间,作为 duration。

fling 的实现很复杂,需要物理和高数的知识(三次样条差值),看不懂。

你可能感兴趣的:(OverScroller)