1. A brief introduction

Android has three kinds of animation, which are view animation, property animation and frame animation.

Among them, frame animation is not recommended to be used in actual development because of its insufficient resources, poor performance, memory overflow and so on.

Interpolator 2

Similar to acceleration in physics, defines the speed at which the animation progress value changes. Default is linear change.

Interpolators defined in Android:

interpolator function
AccelerateDecelerateInterpolator Speed up first, then slow down
LinearInterpolator Default linear, constant speed change, no practical use
AccelerateInterpolator Speed up to the end
DecelerateInterpolator Slow down until complete
OvershootInterpolator Crossing the line turned around,
AnticipateInterpolator Take a small step back and speed up
AnticipateOvershootInterpolator Take a small step back and speed up, pass the finish line by a small amount and then turn back
BounceInterpolator Elastic interpolator, rebound effect of basketball landing
CycleInterpolator cycle

2.1 Custom interpolators

Generally, custom interpolators need to implement the Interceptor interface

Interpolators used by attribute animations should implement the TimeInterpolator interface. Interpolators used by interpolators for tween animations need to implement Interpolator. Interpolator inherits TimeInterceptorCopy the code

interface

//input indicates progress value 0-100%
public interface TimeInterpolator {
 float getInterpolation(float input);
}

public interface Interpolator extends TimeInterpolator {}Copy the code

1. Custom interpolators

package com.cupster.animation;
import android.view.animation.Interpolator;
class SinInterpolater implements Interpolator {
    @Override
    public float getInterpolation(float input) {
        input = input -0.5 f;
        return (float)Math.sin(60*input) + 0.5 f; }}Copy the code

2. Encapsulation and use method

 public static void myAnim(View target ,float. transx){
        ObjectAnimator animator = ObjectAnimator.ofFloat(target ,"translationX",transx);
        animator.setDuration(3000);
        animator.setInterpolator(new SinInterpolater());
        animator.start();
    }
Copy the code

Use 3.

        img = findViewById(R.id.anim_view);
        img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                PropAnimatorHelper.myAnim(view ,0.10.0.10);// Shake left and right after clicking}});Copy the code

4. Effect: Shake left and right after clicking

TypeEvaluator

An estimator is a value rule that defines the animation progress value.

The default FloatEvaluator and IntEvaluator increase linearly according to the progress value.

public class FloatEvaluator implements TypeEvaluator<Number> {

    public Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        returnstartFloat + fraction * (endValue.floatValue() - startFloat); }}Copy the code

For example, the value range from 0 to 100 is 1,2,3,4… , 99100,

Depending on the usage scenario, we can customize the estimator to get, for example: 0,3,6,9… , 96, 13

3.1 Custom estimator

TypeEvaluator interface

public interface TypeEvaluator<T> {
                / / fraction value progress
    public T evaluate(float fraction, T startValue, T endValue);
}
Copy the code

1. Custom estimator

package com.cupster.animation;

import android.animation.TypeEvaluator;

Evaluator: public void setColor; invalidate() */ Evaluator: public void setColor
public class ColorEvaluator implements TypeEvaluator {

    private int mCurrentRed = -1;

    private int mCurrentGreen = -1;

    private int mCurrentBlue = -1;

    @Override
    public Object evaluate(float fraction, Object startValue, Object endValue) {
        String startColor = (String) startValue;
        String endColor = (String) endValue;
        int startRed = Integer.parseInt(startColor.substring(1.3), 16);
        int startGreen = Integer.parseInt(startColor.substring(3.5), 16);
        int startBlue = Integer.parseInt(startColor.substring(5.7), 16);
        int endRed = Integer.parseInt(endColor.substring(1.3), 16);
        int endGreen = Integer.parseInt(endColor.substring(3.5), 16);
        int endBlue = Integer.parseInt(endColor.substring(5.7), 16);
        // Initialize the value of the color
        if (mCurrentRed == -1) {
            mCurrentRed = startRed;
        }
        if (mCurrentGreen == -1) {
            mCurrentGreen = startGreen;
        }
        if (mCurrentBlue == -1) {
            mCurrentBlue = startBlue;
        }
        // Calculate the difference between the start and end colors
        int redDiff = Math.abs(startRed - endRed);
        int greenDiff = Math.abs(startGreen - endGreen);
        int blueDiff = Math.abs(startBlue - endBlue);
        int colorDiff = redDiff + greenDiff + blueDiff;
        if(mCurrentRed ! = endRed) { mCurrentRed = getCurrentColor(startRed, endRed, colorDiff,0,
                    fraction);
        } else if(mCurrentGreen ! = endGreen) { mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff, redDiff, fraction); }else if(mCurrentBlue ! = endBlue) { mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff, redDiff + greenDiff, fraction); }// Return the calculated values of the current color
        String currentColor = "#" + getHexString(mCurrentRed)
                + getHexString(mCurrentGreen) + getHexString(mCurrentBlue);
        return currentColor;
    }

    /** * Calculates the current color based on the fraction value. * /
    private int getCurrentColor(int startColor, int endColor, int colorDiff,
                                int offset, float fraction) {
        int currentColor;
        if (startColor > endColor) {
            currentColor = (int) (startColor - (fraction * colorDiff - offset));
            if(currentColor < endColor) { currentColor = endColor; }}else {
            currentColor = (int) (startColor + (fraction * colorDiff - offset));
            if(currentColor > endColor) { currentColor = endColor; }}return currentColor;
    }

    /** * converts a decimal color value to a hexadecimal value. * /
    private String getHexString(int value) {
        String hexString = Integer.toHexString(value);
        if (hexString.length() == 1) {
            hexString = "0" + hexString;
        }
        returnhexString; }}Copy the code

2. Encapsulation method

   public static void propColorAnimator(ColorTextView target , String startColor , String endColor){
        ObjectAnimator animator = ObjectAnimator.ofObject(target ,"color".new ColorEvaluator() ,startColor,endColor);
        animator.setDuration(3000);
        animator.start();
    }
Copy the code

3. To expand the View

class ColorTextView extends TextView {

    public void setColor(String color){
        setTextColor(Color.parseColor(color));
    }

    public ColorTextView(Context context) {
        super(context);
    }

    public ColorTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs); }}Copy the code

Use 4.

        img = findViewById(R.id.anim_view);
        img.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                PropAnimatorHelper.propColorAnimator((ColorTextView) view,"#a7dbf7" ,"#ff8696"); }});Copy the code