Android Scroller类学习

要实现想Launcher那样的屏幕滑动效果,最基础的要学会scroller类的用法以及view类里面的scrollTo和scrollBy方法。

1.scrollTo(int x, int y);滑动到x,y位置;这里的x,y位置是这样理解的。

   拿TextView来做说明,定义textview时我们将它的长和宽定义为60x30,则该textView可见区域就是60x30的可见区域,但是textView的内容可能很多,比如它的内容是300x100的区域

    则textView.scrollTo(x,y)代表,这会的textView显示的是以300x100区域左上角为坐标原点的,坐标为(x,y,x+60,y+30)这个长方形区域的文字内容。

2.scrollBy(int dx,int dy)源码如下

  public void scrollBy(int x, int y) {
        scrollTo(mScrollX + x, mScrollY + y);
    }

3.Scroller类

  该类中有两个重要的方法

 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;
    }

 该方法一般在ACTION_UP的时候调用,它会协助完成抬笔之后的滑动动作,startX指的是抬笔时的横坐标位置,dx代表横坐标方向滑动的距离,duration代表滑动所需时间。该函数执行之后mFinished = false;此时再调用computeScrollOffset就会返回true,表明滑动的动画没有结束。

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

        int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
    
        if (timePassed < mDuration) {
            switch (mMode) {
            case SCROLL_MODE:/滑动模式
                float x = timePassed * mDurationReciprocal;
    
                if (mInterpolator == null)//检查是否有插入器,在new scroll对象时加入
                    x = viscousFluid(x); 
                else
                    x = mInterpolator.getInterpolation(x);
    
                mCurrX = mStartX + Math.round(x * mDeltaX);//若没有定义插入器则当前的x,y位置由以下方法计算所得
                mCurrY = mStartY + Math.round(x * mDeltaY);
                break;
            case FLING_MODE://猛掷模式
                final float t = (float) timePassed / mDuration;
                final int index = (int) (NB_SAMPLES * t);
                final float t_inf = (float) index / NB_SAMPLES;
                final float t_sup = (float) (index + 1) / NB_SAMPLES;
                final float d_inf = SPLINE[index];
                final float d_sup = SPLINE[index + 1];
                final float distanceCoef = d_inf + (t - t_inf) / (t_sup - t_inf) * (d_sup - d_inf);
                
                mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX));
                // Pin to mMinX <= mCurrX <= mMaxX滑动的位置不能超过fling函数所定义的位置范围
                mCurrX = Math.min(mCurrX, mMaxX);
                mCurrX = Math.max(mCurrX, mMinX);
                
                mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY));
                // Pin to mMinY <= mCurrY <= mMaxY
                mCurrY = Math.min(mCurrY, mMaxY);
                mCurrY = Math.max(mCurrY, mMinY);

                if (mCurrX == mFinalX && mCurrY == mFinalY) {
                    mFinished = true;//动画已结束
                }

                break;
            }
        }
        else {
            mCurrX = mFinalX;
            mCurrY = mFinalY;
            mFinished = true;
        }
        return true;
    }
computeScrollOffset方法主要用于更新现在滑动所到的位置,就是更新mCurrX的值。

public float getCurrVelocity() //该方法用来返回当前的速度

public final void setFriction(float friction)//该方法是设置模拟摩擦力的大小,用以计算当前速度,磨擦力越大速度减缓的越快

public void fling (int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)

  在fling(快滑,用户按下触摸屏、快速移动后松开)手势基础上开始滚动。滚动的距离取决于fling的初速度。

      参数

      startX 滚动起始点X坐标

  startY 滚动起始点Y坐标

  velocityX   当滑动屏幕时X方向初速度,以每秒像素数计算

  velocityY   当滑动屏幕时Y方向初速度,以每秒像素数计算

  minX    X方向的最小值,scroller不会滚过此点。

  maxX    X方向的最大值,scroller不会滚过此点。

  minY    Y方向的最小值,scroller不会滚过此点。

  maxY    Y方向的最大值,scroller不会滚过此点。

 

   

posted on 2012-05-14 16:33  菊者潜之爱  阅读(1001)  评论(0编辑  收藏  举报

导航