利用Scroller实现弹性滑动

使用Scroller

实现弹性滑动的源码如下

Scroller scroller=new Scroller(mContext);

    private void smoothScroolBy(int destx, int desty) { int scrollX=getScrollx(); int deltax=destx-scrollx; mScroller.startScroll(scrollX, 0, deltax, 0,1000); //1000ms内滑向deltax,效果就是慢慢滑 invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } }



原理:
1.构造一个Scroller对象,并调用startScroll方法。Scroller仅用来保存参数,无实际作用
2.invalidate会导致view重绘,draw又会调用computeScroll
3.computeScroll在view中为空方法,所以需要自己实现
4.postInvalidate再次重绘。并且会再次调用computeScroll

另外比较重要的还有computeScrollOffset方法的源码

/**
     * Call this when you want to know the new location.  If it returns true,
     * the animation is not yet finished.
     */ 
    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; case FLING_MODE: final float t = (float) timePassed / mDuration; final int index = (int) (NB_SAMPLES * t); float distanceCoef = 1.f; float velocityCoef = 0.f; if (index < NB_SAMPLES) { final float t_inf = (float) index / NB_SAMPLES; final float t_sup = (float) (index + 1) / NB_SAMPLES; final float d_inf = SPLINE_POSITION[index]; final float d_sup = SPLINE_POSITION[index + 1]; velocityCoef = (d_sup - d_inf) / (t_sup - t_inf); distanceCoef = d_inf + (t - t_inf) * velocityCoef; } mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f; mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX)); // Pin to mMinX <= mCurrX <= mMaxX 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; }
 

猜你喜欢

转载自www.cnblogs.com/pushu/p/11392164.html