当前位置: 首页 > 工具软件 > Overscroll > 使用案例 >

OverScroll介绍

盛辰沛
2023-12-01

OverScroll

OverScroll作用

首先,OverScroll虽然内置了很多看起来像执行滑动效果的方法名,比如startScroll(int, int, int, int),springBack(int, int, int, int, int, int)等等,但是他们并不实际执行滑动效果,只是用于辅助计算,真正的滑动效果需要自己实现。

startScroll为例,查看源码可以发现该方法只是设定了动画参数和相关状态,并没有开启动画

void startScroll(int start, int distance, int duration) {
    mFinished = false;

    mCurrentPosition = mStart = start;
    mFinal = start + distance;

    mStartTime = AnimationUtils.currentAnimationTimeMillis();
    mDuration = duration;

    // Unused
    mDeceleration = 0.0f;
    mVelocity = 0;
}

computeScrollOffset()源码中,可以更加明显的体会到OverScroll作为计算辅助类的作用

switch (mMode) {
    case SCROLL_MODE:
    long time = AnimationUtils.currentAnimationTimeMillis();
    // Any scroller can be used for time, since they were started
    // together in scroll mode. We use X here.
    final long elapsedTime = time - mScrollerX.mStartTime;

    final int duration = mScrollerX.mDuration;
    if (elapsedTime < duration) {
        final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
        mScrollerX.updateScroll(q);
        mScrollerY.updateScroll(q);
    } else {
        abortAnimation();
    }
    break;
        
    ....

该方法也没有进行实现滑动效果,仅在调用时更新滑动参数。那么又是在哪里实现滑动效果?

滑动实现

  • View#overScrollBy

    对传入的值进行校验:是否超出滚动边界,最后实际调用onOverScrolled(newScrollX, newScrollY, clampedX, clampedY)
    由于这个方法参数出其的长,简单说一下各参数的含义
    @param deltaX 需要横向滑动的值,单位px
    @param scrollX 已经横向滑动过的值,单位px
    @param scrollRangeX 最大横向滑动的范围,单位px
    @param maxOverScrollX 最大允许超出横向边界值,单位px
    @param isTouchEvent 是否由touch event触发

    运行记录如下。scrollX表示view当前的位置,deltaX为滑动增量,也即是view将要滑动到的位置。如果允许Over Scroll,那么滑动的范围就是scrollRangeX+maxOverScrollX,到达滑动范围最值后不再滑动。

    I/ScrollData: at scrollX:573 with deltaX:0 range is:920 with maxOver:10
    I/ScrollData: at scrollX:573 with deltaX:34 range is:920 with maxOver:10
    I/ScrollData: at scrollX:607 with deltaX:47 range is:920 with maxOver:10
    I/ScrollData: at scrollX:654 with deltaX:40 range is:920 with maxOver:10
    I/ScrollData: at scrollX:694 with deltaX:49 range is:920 with maxOver:10
    I/ScrollData: at scrollX:743 with deltaX:42 range is:920 with maxOver:10
    I/ScrollData: at scrollX:785 with deltaX:43 range is:920 with maxOver:10
    I/ScrollData: at scrollX:828 with deltaX:42 range is:920 with maxOver:10
    I/ScrollData: at scrollX:870 with deltaX:43 range is:920 with maxOver:10
    I/ScrollData: at scrollX:913 with deltaX:40 range is:920 with maxOver:10
    I/ScrollData: at scrollX:930 with deltaX:33 range is:920 with maxOver:10
    I/ScrollData: at scrollX:930 with deltaX:31 range is:920 with maxOver:10
    I/ScrollData: at scrollX:930 with deltaX:28 range is:920 with maxOver:10
    I/ScrollData: at scrollX:930 with deltaX:10 range is:920 with maxOver:10
    I/ScrollData: at scrollX:930 with deltaX:0 range is:920 with maxOver:10
    I/ScrollData: at scrollX:930 with deltaX:-10 range is:920 with maxOver:10
    
    
  • View#onOverScrolled

    该方法为了响应overScrollBy()的调用,但是这个在View里是没有实现的,需要我们自己实现滑动逻辑。

  • View#scrollTo

    是真正实现滑动效果的方法,设置view滚动位置

  • View#scrollBy

    实际调用scrollTo(mScrollX + x, mScrollY + y)

  • View#computeScroll

    源码注释中解释:由父类调用,在必要时更新子类mScrollX 和 mScrollY的值。作用类似于ValueAnimator.AnimatorUpdateListener的功能,由invalidate()调用,用于在动画效果中实时更新mScrollX和mScrollY,并对其做出相应的滑动响应。

如何使用

  1. 初始化OverScroll对象,默认使用非粘性流体插值器,如果需要可以额外指定插值器。
  2. 通过OverScroll提供方法,如startscroll等,设定动画效果,并开始计算滑动效果中x,y值。注意此时并没有开始滑动动画
  3. 通知view更新
  4. computeScroll方法中根据OverScroll计算值,通过scrollTo等方法,执行实际滑动效果
  5. 通知view更新

重复执行step.4,step.5知道滑动效果结束。

参考:
How to use Android scroller
cy overscrollby 介绍

 类似资料: