android develops an operation example of transitional sliding effect through Scroller

  • 2021-11-14 07:12:44
  • OfStack

In this paper, an example is given to describe the transition sliding effect realized by android development through Scroller. Share it for your reference, as follows:

Mainly introduces 1 Scroller this class, it can achieve the effect of transition sliding, so that sliding looks not so stiff, of course, it uses a lot of redrawing to achieve, invalidate (); Look through the source code:

Look at the construction method


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

We use the default on the line, pass a context on the line, other what difference device, no matter first

Then we call startScroll, passing us the offset of the slide that discriminates against the slide position and slide, and the optional default duration, which defaults to 250 milliseconds
This method is used to assign values, and then invalidate () is called to redraw, and then onDraw () is called
computeScroll () This method, we rewrite this method, computeScrollOffset () is a method to judge whether the animation has ended. When it doesn't end, we move according to the offset position of sliding, that is, the current position of scrollto to scroller, and call invalidate () again, thus countless returns are spliced to form a smooth sliding


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


 public void startScroll(int startX, int startY, int dx, int dy) {
    startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
  }
 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;
  }


public class MoveFreeView extends View{
  private int movedX;
  private int movedY;
  private Scroller mScroller;
  public MoveFreeView(Context context) {
    super(context);
  }
  public MoveFreeView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    mScroller = new Scroller(context);
  }
  public MoveFreeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    // Get touch point to boundary coordinates 
    int x = (int) event.getX();
    int y = (int) event.getY();
    switch (event.getAction()){
      case MotionEvent.ACTION_DOWN:
        movedX = x;
        movedY = y;
        break;
      case MotionEvent.ACTION_MOVE:
        int offsetX = x-movedX;
        int offsetY = y-movedY;
        layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
        break;
    }
    return super.onTouchEvent(event);
  }
  // For external calls by passing x , y Sliding distance of 
  public void smoothScrollTo(int destinyX,int destinyY){
    // To the right , Slide down, please pass a negative value 
    int scrollX = getScrollX();
    int scrollY = getScrollY();
    int delta = destinyX - scrollX;
    int deltaY = destinyY - scrollY;
    mScroller.startScroll(scrollX,scrollY,delta,deltaY,5000);
    invalidate();
  }
  @Override
  public void computeScroll() {
    super.computeScroll();
    //true The slide is not over 
    if (mScroller.computeScrollOffset()){
      ((View) getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
      invalidate();
    }
  }
}


private MoveFreeView button;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button = (MoveFreeView) findViewById(R.id.custon);
    button.smoothScrollTo(-400,-300);
    //    button.startAnimation(AnimationUtils.loadAnimation(this,R.anim.translate));
//    ObjectAnimator animtor1 = ObjectAnimator.ofFloat(button, "translationX", 0, 300);
//    ObjectAnimator animtor2 = ObjectAnimator.ofFloat(button, "translationY", 0, 300);
//    ObjectAnimator animator3 = ObjectAnimator.ofFloat(button,"rotationX",0.0f,360f);
//    ObjectAnimator animator4 = ObjectAnimator.ofFloat(button,"scaleX",1.5f,0.5f);
//    AnimatorSet set= new AnimatorSet();
//    set.setDuration(5000);
//    set.playTogether(animtor1,animtor2,animator3,animator4);
//    set.addListener(new Animator.AnimatorListener() {
//      @Override
//      public void onAnimationStart(Animator animator) {
//
//      }
//
//      @Override
//      public void onAnimationEnd(Animator animator) {
//        // Do it at the end of animation 1 Something 
//      }
//
//      @Override
//      public void onAnimationCancel(Animator animator) {
//
//      }
//
//      @Override
//      public void onAnimationRepeat(Animator animator) {
//
//      }
//    });
//    set.start();
  }
}

For more readers interested in Android related content, please check the topics on this site: "Introduction and Advanced Tutorial of Android Development", "Summary of Android Debugging Skills and Common Problem Solutions", "Summary of Android Basic Component Usage", "Summary of View Skills in Android View", "Summary of layout Skills in Android Layout" and "Summary of Android Control Usage"

I hope this article is helpful to everyone's Android programming.


Related articles: