Android滑屏学习总结

来源:互联网 发布:2016淘宝发布宝贝教程 编辑:程序博客网 时间:2024/06/16 11:21

1、初识 scrollTo scrollBy

protected int mScrollX;   //该视图内容相当于视图起始坐标的偏移量

protected int mScrollY;   //该视图内容相当于视图起始坐标的偏移量

public void scrollTo(int x, int y) {      //偏移位置发生了改变       if (mScrollX != x || mScrollY != y) {          int oldX = mScrollX;          int oldY = mScrollY;          mScrollX = x;            mScrollY = y;          //回调onScrollChanged方法           onScrollChanged(mScrollX, mScrollY, oldX, oldY);          if (!awakenScrollBars()) {              invalidate();  //一般都引起重绘           }      }  }  public void scrollBy(int x, int y) {        scrollTo(mScrollX + x, mScrollY + y);  }  

scrollTo scrollBy从原代码来看这二个其实是同一个。最简单的滑屏,但速度过快(瞬秒),产生不好体验,于是在这个过程中加入一组渐变过程~

2、Scroller类 利用startScroll()对偏移进行控制

private int mStartX;    //起始坐标点private int mStartY;    //起始坐标点  private int mCurrX;     //当前坐标点   即调用startScroll函数后,经过一定时间所达到的值   private int mCurrY;     //当前坐标点   即调用startScroll函数后,经过一定时间所达到的值   private int mFinalX;private int mFinalY;private float mDeltaX;  //应该继续滑动的距离, X轴方向   private float mDeltaY;  //应该继续滑动的距离, Y轴方向   private boolean mFinished;  //是否已经完成本次滑动操作, 如果完成则为 true 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;        // This controls the viscous fluid effect (how much of it)        mViscousFluidScale = 8.0f;        // must be set to 1.0 (used in viscousFluid())        mViscousFluidNormalize = 1.0f;        mViscousFluidNormalize = 1.0f / viscousFluid(1.0f);    }


 在view的绘制过程时.会在draw()过程中调用computeScroll()在dispatchDraw()中会调用drawChild().在drawChild()中又会调用computeScroll().通过在computeScrollOffset()中计算偏移坐标后再调用scrollBy()达到缓慢滑动效果

public boolean computeScrollOffset() {        if (mFinished) {            return false;        }        int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);            if (timePassed < mDuration) {            switch (mMode) {            case SCROLL_MODE:                float x = (float)timePassed * mDurationReciprocal;                    if (mInterpolator == null)                    x = viscousFluid(x);                 else                    x = mInterpolator.getInterpolation(x);                    mCurrX = mStartX + Math.round(x * mDeltaX);                mCurrY = mStartY + Math.round(x * mDeltaY);                break;            case FLING_MODE:                float timePassedSeconds = timePassed / 1000.0f;                float distance = (mVelocity * timePassedSeconds)                        - (mDeceleration * timePassedSeconds * timePassedSeconds / 2.0f);                                mCurrX = mStartX + Math.round(distance * mCoeffX);                // Pin to mMinX <= mCurrX <= mMaxX                mCurrX = Math.min(mCurrX, mMaxX);                mCurrX = Math.max(mCurrX, mMinX);                                mCurrY = mStartY + Math.round(distance * mCoeffY);                // Pin to mMinY <= mCurrY <= mMaxY                mCurrY = Math.min(mCurrY, mMaxY);                mCurrY = Math.max(mCurrY, mMinY);                                break;            }        }        else {            mCurrX = mFinalX;            mCurrY = mFinalY;            mFinished = true;        }        return true;    }

总结:通过scroller类-->startScroll-->引发draw调用dispatchDraw()-->drawChild()-->computeScroll().通常我们要实现computeScroll()此方法然后根据computeScrollOffset(){..scrollTo(mScroller.getCurrX(), mScroller.getCurrY());...}实现滑屏.computeScroll()会不停调用直到滑屏停止~