Android Loading Circle Animation

In this Post, I am to tell about how to create own android loading circle animation. Basically, The output will be in View So that you can easily add it in your xml layout file.

Android Loading Circle Animation
Android Loading Circle Animation

Please follow the steps to create android loading circle animation.
Before going to start First create new Android Studio Project.


Android ConstraintLayout Example

Create Reusable Alert Dialog in Android


Step 1 : CricleView
First, we need to create circleview by extending the View Class. Then Override onDraw() method.

public class CircleView extends View {

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

    }
}

Now, the View is ready to draw the circle.
Create RectF with left , top, right and bottom position of the circle. Once RectF created draw arc using RectF and Paint.

Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(strokeWidth);
paint.setColor(Color.GRAY);

RectF rectF = new RectF();
rectF.set(strokeWidth,strokeWidth,getWidth() - strokeWidth  ,getWidth() - strokeWidth);
canvas.drawArc(rectF,0,360,false,paint);

Now the background circle is Ready.


shimmer effect For Android Recyclerview Example

Glide – Image loading framework for Android with Example [Part 1]


Step 2:  Loading Circle Animation
In your MainActivity, Create the value animator and pass the animated values to the circle view to create the circle arc animation.

final ValueAnimator valueAnimator = ValueAnimator.ofInt(1,360);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setDuration(1000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
         Log.d("Anim",animation.getAnimatedValue()+"");
         circleView.setValue((Integer) animation.getAnimatedValue());
      }
    });
valueAnimator.start();

In your CircleView, Update the circle starting position depends on the animated value. and do invalidate of the view.

@Override
   protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);

       Paint paint = new Paint();
       paint.setStyle(Paint.Style.STROKE);
       paint.setStrokeWidth(strokeWidth);
       paint.setColor(Color.GRAY);

       RectF rectF = new RectF();
       rectF.set(strokeWidth,strokeWidth,getWidth() - strokeWidth  ,getWidth() - strokeWidth);
       canvas.drawArc(rectF,0,360,false,paint);
       paint.setColor(Color.BLUE);
       canvas.drawArc(rectF,animValue,80,false,paint);
   }

   public void setValue(int animatedValue) {
       animValue = animatedValue;
       invalidate();
   }

here 80 is the arc sweep angle, you can increase or decrease the arc length using that sweep angle value.

final CircleView.java

package circlegraph.velmurugan.com.infinitycircle;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View {

    private int animValue;
    private int strokeWidth = 15;

    public CircleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        animValue = 0;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(strokeWidth);
        paint.setColor(Color.GRAY);

        RectF rectF = new RectF();
        rectF.set(strokeWidth,strokeWidth,getWidth() - strokeWidth  ,getWidth() - strokeWidth);
        canvas.drawArc(rectF,0,360,false,paint);
        paint.setColor(Color.BLUE);
        canvas.drawArc(rectF,animValue,80,false,paint);
    }

    public void setValue(int animatedValue) {
        animValue = animatedValue;
        invalidate();
    }

}

MainActivity.java

package circlegraph.velmurugan.com.infinitycircle;

import android.animation.ValueAnimator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.animation.LinearInterpolator;

import java.lang.annotation.Repeatable;

public class MainActivity extends AppCompatActivity {


    CircleView circleView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        circleView = findViewById(R.id.circleView);

        final ValueAnimator valueAnimator = ValueAnimator.ofInt(1,360);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setDuration(1000);
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.d("Anim",animation.getAnimatedValue()+"");
                circleView.setValue((Integer) animation.getAnimatedValue());
            }
        });

        valueAnimator.start();

    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <circlegraph.velmurugan.com.infinitycircle.CircleView
        android:id="@+id/circleView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true" />

</RelativeLayout>

Download

Also, Checkout same exmple code in github.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top