Hello, everyone. Today, I introduce a very simple countdown animation, which mimics the start page countdown effect of cool dog music. It is also an animation used by most apps.

Implementation approach

See if it is very simple, draw a circle to move, the whole idea is to use a smooth frame animation to draw arc on the line.

What does the passage learn?

  • Understanding property animationValueAnimatorThe use of the
  • Learn about animation property interpolationInterpolatorTo make the animation transition more natural
  • How to draw an arc

To start preparing

Create a new class that inherits the TextView. Because there is skipped text in the middle, I chose to draw a moving background with the TextView.

/** * Created by ChenRui on 2017/10/31 0031 23:01. */
public class CountDownTextView extends RaeTextView {
    // Count down the animation time
    private int duration = 5000;
    // The Angle of the animation sweep
    private int mSweepAngle = 360;
    // Property animation
    private ValueAnimator animator;
    // Rectangle is used to store location size information
    private final RectF mRect = new RectF();
    // Arc pen
    private Paint mBackgroundPaint;

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

    public CountDownTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CountDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    void init(a) {
        super.init();
        // Set brush smoothing
        mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // Set the brush color
        mBackgroundPaint.setColor(Color.WHITE);
        // Set the brush border width
        mBackgroundPaint.setStrokeWidth(dp2px(2));
        // Set the brush style to border type
        mBackgroundPaint.setStyle(Paint.Style.STROKE);
    }
Copy the code

Start the animation

Principle: Use the 360-degree Angle of the circle to animate the property, let it smoothly assign the Angle value of each frame of the animation, and then call invalidate() to redraw itself, thus entering its own onDraw() method to draw the picture.

  /**
     * 开始倒计时
     */
    public void start(a) {
        // In the animation
        if(mSweepAngle ! =360) return;
        // Initialize the property animation
        animator = ValueAnimator.ofInt(mSweepAngle).setDuration(duration);
        // Set the interpolation
        animator.setInterpolator(new LinearInterpolator());
        // Set the animation listener
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // Gets the animation value returned by the property animation
                mSweepAngle = (int) animation.getAnimatedValue();
                // Redraw yourselfinvalidate(); }});// Start animation
        animator.start();
    }
Copy the code

Draw arc

It’s easy to draw an arc. If you want to draw an arc, you might think that you want to draw two circles, an inner circle with a background and a large circle with a white border. In fact, you can use the paintbrush Settings paint.setStyle() and paint.setstrokeWidth (). The code is simple. Start at -90 and draw from the top of the head. The result is a clockwise countdown. If you want the counterclockwise effect, set mSweepAngle to mSweepAngle = 360-msweepAngle.

 @Override
    protected void onDraw(Canvas canvas) {
        int padding = dp2px(4);
        mRect.top = padding;
        mRect.left = padding;
        mRect.right = getWidth() - padding;
        mRect.bottom = getHeight() - padding;

        // Draw the inner circle of the countdown line
        canvas.drawArc(mRect, // The size of the rectangle used for the arc
                -90.// Start Angle
                mSweepAngle, // Sweep the Angle
                false.// Whether to use the center
                mBackgroundPaint); // Set the brush

        super.onDraw(canvas);
    }
Copy the code

What is interpolation animation?

In order to make the animation transition more natural or add some animation effects, such as uniform motion, accelerated motion, deceleration motion, bounce motion and so on, these animation effects are achieved by interpolation. In Android system built-in some interpolation, here to do a porter record. Recommend a can run online Interpolator and the effect of mathematical formula defined site inloop. Making. IO/interpolato… A more intuitive demonstration of the animation effects described below.

The interpolation instructions
LinearInterpolator Changing at a constant rate
BounceInterpolator When the animation ends, it bounces
CycleInterpolator The animation loops a certain number of times and the rate changes along a sinusoidal curve
DecelerateInterpolator Fast and slow at the beginning of the animation
OvershootInterpolator Throw forward for a certain amount and return to the original position
AccelerateInterpolator The rate changes slowly at the beginning of the animation and then begins to accelerate
AnticipateInterpolator Start swinging backwards and forward
AccelerateDecelerateInterpolator The rate changes slowly at the beginning and introduction of the animation and speeds up in the middle
AnticipateOvershootInterpolator It starts with a backward swing and then a forward swing and returns the final value

Projects using

Here I need to define the width and height of the text, as there is no black circle at the bottom, and also set the background image.

  <com.rae.cnblogs.widget.CountDownTextView
            android:id="@+id/tv_skip"
            style="@style/Widget.AppCompat.Button.Borderless"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="@drawable/bg_count_down"
            android:text="Skip"
            android:textColor="#ffffff"
            android:textSize="12sp" />
Copy the code

background

<?xml version="1.0" encoding="utf-8"? >
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="oval">
            <solid android:color="#302d2d2d" />
        </shape>
    </item>
    <item>
        <shape android:shape="oval">
            <solid android:color="#7F2d2d2d" />
        </shape>
    </item>
</selector>
Copy the code

End here, I hope to help you, the source of this article are in the open source Blog garden Android client here. Like to give a start~~