当前位置 主页 > 网站技术 > 代码类 >

    android开发通过Scroller实现过渡滑动效果操作示例

    栏目:代码类 时间:2020-01-22 15:06

    本文实例讲述了android开发通过Scroller实现过渡滑动效果。分享给大家供大家参考,具体如下:

    主要介绍一下Scroller这个类,它可以实现过渡滑动的效果,使滑动看起来不是那么生硬,当然它用大量的重绘来实现,invalidate();通过源码看:

    看构造方法

     /**
       * Create a Scroller with the default duration and interpolator.
       */
      public Scroller(Context context) {
        this(context, null);
      }
      /**
       * Create a Scroller with the specified interpolator. If the interpolator is
       * null, the default (viscous) interpolator will be used. "Flywheel" behavior will
       * be in effect for apps targeting Honeycomb or newer.
       */
      public Scroller(Context context, Interpolator interpolator) {
        this(context, interpolator,
            context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB);
      }
      /**
       * Create a Scroller with the specified interpolator. If the interpolator is
       * null, the default (viscous) interpolator will be used. Specify whether or
       * not to support progressive "flywheel" behavior in flinging.
       */
      public Scroller(Context context, Interpolator interpolator, boolean flywheel) {
        mFinished = true;
        if (interpolator == null) {
          mInterpolator = new ViscousFluidInterpolator();
        } else {
          mInterpolator = interpolator;
        }
        mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
        mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
        mFlywheel = flywheel;
        mPhysicalCoeff = computeDeceleration(0.84f); // look and feel tuning
      }
    
    

    我们用默认的就行,传个context就行了,其他的什么差值器,先不管了

    然后调用startScroll,传递我们歧视滑动位置和滑动的偏移量,还有可选的默认持续时间,默认为250毫秒
    这个方法是用来赋值的,接下来会调用invalidate()进行重新绘制,然后就会onDraw(),这时候会调用
    computeScroll()这个方法,我们重写这个方法,computeScrollOffset()是判断动画有没有结束的一个方法,没结束的时候,我们根据滑动的偏移位置进行移动也就是scrollto到scroller的当前位置,再次调用invalidate(),由此无数的重回进行拼接形成了平滑的滑动

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