OverScroller

OverScroller 是 Scroller 的加強版,增加了滾出視圖范圍之后的回彈效果,但這個效果最好還是別用了。

OverScroller 是一個輔助類,用來實現(xiàn)視圖的平滑滾動。
說道平滑,實質(zhì)就是利用系統(tǒng)重畫的間隔,16ms(實際值),不斷重新計算值并重畫。無論是使用 ValueAnimator ,還是 OverScroller ,本質(zhì)都是一樣的。

平滑滾動

GIF.gif

滾動的實質(zhì)是移動了畫布的原點,所以視圖本身的坐標(biāo)和大小都沒發(fā)生變化,依舊能觸發(fā)點擊事件。

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) {
  // 根據(jù)過去的時間計算滾動距離,線性插值器就是 Y=X,其他差值器也會經(jīng)過(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 作為滾動結(jié)束條件的。
fling 則是捕捉一個 fling 事件,獲取出初始速度(模擬滑動的慣性),然后設(shè)置一定的阻力,計算出速度消減為 0 所需的時間,作為 duration。

fling 的實現(xiàn)很復(fù)雜,需要物理和高數(shù)的知識(三次樣條差值),看不懂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容