Property animation basic notes

Modify custom attributes

  • Create a custom View as follows:
public class CicleView extends View {
   private Paint paint;
   private float radius;

   public CicleView(Context context) {
       super(context);
       init(context, null);
   }

   public CicleView(Context context, @Nullable AttributeSet attrs) {
       super(context, attrs);
       init(context, attrs);
   }

   public CicleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
       super(context, attrs, defStyleAttr);
       init(context, attrs);
   }

   public void setRadius(float radius) {
       this.radius = radius;
       invalidate();
   }

   private void init(Context context, AttributeSet attrs) {
       paint = new Paint();
       paint.setColor(Color.BLUE);
       paint.setAntiAlias(true);
       paint.setMaskFilter(new BlurMaskFilter(2f, BlurMaskFilter.Blur.NORMAL));
   }


   @Override
   protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);
       int cx = getWidth() / 2;
       int cy = getHeight() / 2;
       canvas.drawCircle(cx, cy, radius, paint);
   }
}
  • Use Animator to change attributes
 //使用ObjectAnimator
       ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "radius", 0, 120, 240, 360);
       objectAnimator.setDuration(2000);
       objectAnimator.setRepeatCount(100);
       objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
       objectAnimator.start();
       //使用ValueAnimator
       ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 120, 240, 360);
       valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
           @Override
           public void onAnimationUpdate(ValueAnimator animation) {
               float value = (float) animation.getAnimatedValue();
               iv.setRadius(value);
           }
       });
       valueAnimator.start();

Interpolator-TimeInterpolator

  • During the playback of the animation, Android provides an interpolator to change the playback rate of the animation, and uses different interpolators to achieve different playback effects. All interpolators must implement the TimeInterpolator interface.

10 types of interpolators implemented by default in Android

  • AccelerateDecelerateInterpolator
    • Effect: The speed of change is getting slower and slower,
    • The return value of the getInterpolation(float input) method is (Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; cos curve
  • AccelerateInterpolator
    • Effect: The speed of change is getting faster and faster
    • getInterpolation(float input) The return value is: input to the 2N power
  • AnticipateInterpolator
    • Effect: the speed of change starts fast, then slows down
    • getInterpolation(float t) The return value is: (k+1)*t 3-k*t 2
  • AnticipateOvershootInterpolator
    • Effect: The speed of change starts fast, then slows down, and finally there is a rebound effect, rebound once.
    • getInterpolation(float t) 返回值:
      a(t, s) = t * t * ((s + 1) * t - s);
      o(t, s) = t * t * ((s + 1) * t + s);
      f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5;
      f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0;
  • BounceInterpolator
    • Effect: The speed of change is getting faster and faster, and finally there is a rebound vibration effect.
    • getInterpolation(float t) 返回值:_b(t) = t * t * 8;
      bs(t) = _b(t) for t < 0.3535;
      bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408;
      bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644;
      bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0;
      b(t) = bs(t * 1.1226);
  • CycleInterpolator(float cycles)
    • Effect: the specified number of cycles (cycles), the rate of change is the sin function
    • getInterpolation(float input) Return value: (Math.sin(2 * mCycles * Math.PI * input));
  • DecelerateInterpolator
    • Effect: The speed of change is getting slower and slower
    • getInterpolation(float input) The return value is 1-(1-input)^2n of input
  • LinearInterpolator
    • Effect: uniform change
    • getInterpolation(float input) return value: input
      -LinearOutSlowInInterpolator
    • Effect: uniform speed at first, then slower and slower
  • OvershootInterpolator
    • Effect: At first, the speed is constant, and then it will rebound once.
    • getInterpolation(float input) return value:
      _o(t) = t * t * ((tension + 1) * t + tension);
      o(t) = _o(t-1) + 1;

Custom TimeInterpolator

  • Inherit the BaseInterpolator class
  • Override the float getInterpolation(float input) method. Return different values ​​according to certain conditions.
public class CustomInterpolator extends BaseInterpolator {
   @Override
   public float getInterpolation(float input) {
       return 0;
   }
}

Evaluator-TypeEvaluator

  • It is used to determine the specific value of the animation at every moment in the animation process. In other words, it is to determine the specific object type returned by ValueAnimator.getAnimatedValue().

The estimator implemented by default in Android

  • ArgbEvaluator
  • FloatArrayEvaluator
  • FloatEvaluator
  • IntArrayEvaluator
  • IntEvaluator
  • PointFEvaluator
  • RectEvaluator

Custom Evaluator

  • Implement TypeEvaluator interface
  • Override the T evaluate(float fraction, T startValue, T endValue) method. Return different values ​​according to certain conditions.
 class CustomEvaluator implements TypeEvaluator<Number> {

        @Override
        public Number evaluate(float fraction, Number startValue, Number endValue) {
            return null;
        }
    }

Reimplement the above example

  • Create a dot entity class
/**
 * 圆形的实体类
 */
public class Cicle {
    //圆点x坐标
    private float xCenter;
    //圆点y坐标
    private float yCenter;
    //半径
    private float radius;

    public Cicle() {
    }

    public Cicle(float xCenter, float yCenter, float radius) {
        this.xCenter = xCenter;
        this.yCenter = yCenter;
        this.radius = radius;
    }

    public float getxCenter() {
        return xCenter;
    }

    public void setxCenter(float xCenter) {
        this.xCenter = xCenter;
    }

    public float getyCenter() {
        return yCenter;
    }

    public void setyCenter(float yCenter) {
        this.yCenter = yCenter;
    }

    public float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
    }
}
  • Custom View to draw a circle
public class CicleView extends View {
    private Paint paint;
    private Cicle cicle;

    public CicleView(Context context) {
        super(context);
        init();
    }

    public CicleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CicleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void setCicle(Cicle cicle) {
        this.cicle = cicle;
        invalidate();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setAntiAlias(true);
        paint.setMaskFilter(new BlurMaskFilter(2f, BlurMaskFilter.Blur.NORMAL));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        cicle.setxCenter(width / 2);
        cicle.setyCenter(height / 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(cicle.getxCenter(), cicle.getyCenter(), cicle.getRadius(), paint);
    }
}
  • Custom estimator
 class CustomEvaluator implements TypeEvaluator<Cicle> {

        @Override
        public Cicle evaluate(float fraction, Cicle startValue, Cicle endValue) {
            Log.d(TAG, "evaluate: f:" + fraction + ";;startR:" + startValue.getRadius() + ";;" +
                    endValue.getRadius());
            Cicle cicle = new Cicle();
            cicle.setxCenter((width) / 2);
            cicle.setyCenter((height) / 2);
            cicle.setRadius((endValue.getRadius() - startValue.getRadius()) * fraction);
            return cicle;
        }
    }
  • Realize the animation
        width = getWindowManager().getDefaultDisplay().getWidth();
        height = getWindowManager().getDefaultDisplay().getHeight();
        Cicle cicle1 = new Cicle();
        cicle1.setRadius(0);
        Cicle cicle2 = new Cicle();
        cicle2.setRadius(500);
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new CustomEvaluator(), cicle1, cicle2);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setDuration(5000);
        valueAnimator.setEvaluator(new CustomEvaluator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Cicle cicle = (Cicle) animation.getAnimatedValue();
                iv.setCicle(cicle);
            }
        });
        valueAnimator.start();

Guess you like

Origin blog.csdn.net/genmenu/article/details/88659777