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
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);
}
}