Android Scroller解析和使用

1. Scroller的官方api:

This class encapsulates scrolling. You can use scrollers (Scroller or OverScroller) to collect the data you need to produce a scrolling animation—for example, in response to a fling gesture.

大致意思:
这个类封装了滑动。您可以使用滚动条(Scroller或OverScroller)来收集产生滚动动画所需的数据,例如,响应一个手指动作。

2 先介绍一下实现View的滑动通过如下几种方式:

2.1 View自身的ScrollTo/ScrollBy方法,进行View的滑动
2.2 通过动画将View进行平移效果实现滑动
2.3 改变View的LayoutParams使View进行重新布局绘制是实现滑动

3 使用ScrollTo/ScrollBy实现View的滑动:

ScrollTo和ScrollBy都可以实现View的滑动,但是有什么区别?



3.1简单解释一下

scrollTo: 将自己的View滑动到(x,y)的位置,如果已在(x,y)的位置,则不会有任何滑动的效果
scrollBy: 将自己的View滑动相对于自己的(x,y)的位置,即使在(x,y)的位置,也会发生滑动,因为是相对于View本身
为什么要去解释这个方法的使用:因为在Scroller里面的方法中,使用的就是这两个方法。

4 接下来开始真正的解析Scroller的使用


以下是官方使用example:

 private Scroller mScroller = new Scroller(context);
 ...
 public void zoomIn() {
     // Revert any animation currently in progress
     mScroller.forceFinished(true);
     // Start scrolling by providing a starting point and
     // the distance to travel
     mScroller.startScroll(0, 0, 100, 0);
     // Invalidate to request a redraw
     invalidate();
 }

在看看startScroll()的具体实现

   public void startScroll(int startX, int startY, int dx, int dy, int duration) {
       mMode = SCROLL_MODE;
       mFinished = false;
       mDuration = duration;
       mStartTime = AnimationUtils.currentAnimationTimeMillis();
       mStartX = startX;
       mStartY = startY;
       mFinalX = startX + dx;
       mFinalY = startY + dy;
       mDeltaX = dx;
       mDeltaY = dy;
       mDurationReciprocal = 1.0f / (float) mDuration;
   }

我们会发现startScroll()方法内部并没有实现相关的滑动的代码,那View是如何滑动的?你是否看见了当调用玩startScroll()方法后,执行了一行

        // Invalidate to request a redraw
        invalidate();

在invalidate()方法中会执行一系列的操作(测量绘制等),然后才会出现View的滑动

当然仅仅调用startScroll()方法是不会有弹性滑动的效果,也就是说有一个过渡动画。当然Google也提供了进行自定义滑动的弹性动画,通过重写computeScroll()方法进行实现:如下

   @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }

也就是去计算滑动:scrollTo(mScroller.getCurrX(), mScroller.getCurrY());scrollTo()方法我们在上面已经介绍过了,那么mScroller.getCurrX()是什么鬼,我们继续看源码:

    /**
     * Returns the current X offset in the scroll. 
     * 返回滑动中的当前X的偏移量
     * @return The new X offset as an absolute distance from the origin.
     */
    public final int getCurrX() {
        return mCurrX;
    }

可以看到返回了一个 mCurrX对象,那么mCurrX是如何赋值的?

   public boolean computeScrollOffset() {
        if (mFinished) {
            return false;
        }

        int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
    
        if (timePassed < mDuration) {
            switch (mMode) {
            case SCROLL_MODE:
                final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
                mCurrX = mStartX + Math.round(x * mDeltaX);
                mCurrY = mStartY + Math.round(x * mDeltaY);
                break;
}

就可以看出mCurrX 是根据时间差值和差值器综合计算出来的滑动的距离。到这里我们就会明白,只要computeScrollOffset()返回true ,即还没有滑动结束,则会一直调用scrollTo()和invalidate()方法,进行View的滑动。

猜你喜欢

转载自blog.csdn.net/qq_15988951/article/details/78852234