Android Studio - How to create a Progress bar with NEON Effect
colors.xml
/* Code From Learnoset - Learn Coding Online.
Download Learnoset App from PlayStore to learn coding,
projects, algorithms, error handling
*/
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="neon_body">#00B8D4</color>
<color name="neon_glow">#CC00B8D4</color>
</resources>
activity_main.xml
/* Code From Learnoset - Learn Coding Online.
Download Learnoset App from PlayStore to learn coding,
projects, algorithms, error handling
*/
<?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"
android:background="#000000"
tools:context=".MainActivity">
<com.learnoset.neonprogressbar.MaterialNeonProgressBar
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
AnimatorCreator.java
/* Code From Learnoset - Learn Coding Online.
Download Learnoset App from PlayStore to learn coding,
projects, algorithms, error handling
*/
package com.learnoset.neonprogressbar;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.graphics.Path;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import androidx.core.view.animation.PathInterpolatorCompat;
public class AnimatorCreator {
private static final int SWEEP_DURATION = 1333;
private static final int ROTATION_DURATION = 6665;
private static final float END_ANGLE_MAX = 360;
private static final float START_ANGLE_MAX = END_ANGLE_MAX - 1;
private static final int ROTATION_END_ANGLE = 719;
public AnimatorCreator() {
}
public static Animator create(AnimatorTargetInterface targetInterface){
AnimatorSet animatorSet = new AnimatorSet();
Animator startAngleAnimator = createStartAngleAnimator(targetInterface);
Animator endAngleAnimator = createEndAngleAnimator(targetInterface);
Animator rotationAnimator = createRotationAnimator(targetInterface);
animatorSet.playTogether(startAngleAnimator, endAngleAnimator, rotationAnimator);
return animatorSet;
}
private static Animator createStartAngleAnimator(AnimatorTargetInterface targetInterface){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(targetInterface, targetInterface.START_ANGLE, 0f, START_ANGLE_MAX);
objectAnimator.setDuration(SWEEP_DURATION);
objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
objectAnimator.setRepeatMode(ValueAnimator.RESTART);
objectAnimator.setInterpolator(createStartInterpolator());
return objectAnimator;
}
private static Animator createEndAngleAnimator(AnimatorTargetInterface targetInterface){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(targetInterface, targetInterface.END_ANGLE, 0f, END_ANGLE_MAX);
objectAnimator.setDuration(SWEEP_DURATION);
objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
objectAnimator.setRepeatMode(ValueAnimator.RESTART);
objectAnimator.setInterpolator(createEndInterpolator());
return objectAnimator;
}
private static Animator createRotationAnimator(AnimatorTargetInterface targetInterface){
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(targetInterface, targetInterface.ROTATION, 0f, ROTATION_END_ANGLE);
objectAnimator.setDuration(ROTATION_DURATION);
objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
objectAnimator.setRepeatMode(ValueAnimator.RESTART);
objectAnimator.setInterpolator(new LinearInterpolator());
return objectAnimator;
}
private static Interpolator createStartInterpolator(){
Path path = new Path();
path.cubicTo(0.3f, 0f, 0.1f, 0.75f, 0.5f, 0.85f);
path.lineTo(1f, 1f);
return PathInterpolatorCompat.create(path);
}
private static Interpolator createEndInterpolator(){
Path path = new Path();
path.lineTo(0.5f, 0.1f);
path.cubicTo(0.7f, 0.15f, 0.6f, 0.75f, 1f, 1f);
return PathInterpolatorCompat.create(path);
}
interface AnimatorTargetInterface{
String START_ANGLE = "startAngle";
String END_ANGLE = "endAngle";
String ROTATION = "rotation";
void setStartAngle(float startAngle);
void setEndAngle(float endAngle);
void setRotation(float rotation);
}
}
MaterialNeonProgressBar.java
/* Code From Learnoset - Learn Coding Online.
Download Learnoset App from PlayStore to learn coding,
projects, algorithms, error handling
*/
package com.learnoset.neonprogressbar;
import android.animation.Animator;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
public class MaterialNeonProgressBar extends View implements AnimatorCreator.AnimatorTargetInterface {
private static final float BODY_STROKE_WIDTH = 12f;
private static final float GLOWING_MULTIPLIER = 2;
private static final float BLUE_MULTIPLIER = 1.5f;
private float mPaddingPx;
private Paint mBodyPaint;
private Paint mGlowingPaint;
private RectF mBounds;
private float mStartAngle;
private float mEndAngle = 270;
private float mRotation;
private Animator mAnimator;
public MaterialNeonProgressBar(Context context) {
super(context);
init();
}
public MaterialNeonProgressBar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public MaterialNeonProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
public void setStartAngle(float startAngle) {
mStartAngle = startAngle;
invalidate();
}
@Override
public void setEndAngle(float endAngle) {
mEndAngle = endAngle;
invalidate();
}
@Override
public void setRotation(float rotation) {
mRotation = rotation;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
if(!mAnimator.isRunning()){
mAnimator.start();
}
float start = mRotation + mStartAngle;
float sweep = mEndAngle - mStartAngle;
canvas.drawArc(mBounds, start, sweep, false, mGlowingPaint);
canvas.drawArc(mBounds, start, sweep, false, mBodyPaint);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBounds.set(mPaddingPx, mPaddingPx, w - mPaddingPx, h - mPaddingPx);
}
private static Paint createBodyPaint(Context context, float strokeWidth){
int bodyColor = ResourcesCompat.getColor(context.getResources(), R.color.neon_body, null);
Paint bodyPaint = new Paint();
bodyPaint.setAntiAlias(true);
bodyPaint.setColor(bodyColor);
bodyPaint.setStrokeWidth(strokeWidth);
bodyPaint.setStyle(Paint.Style.STROKE);
bodyPaint.setStrokeJoin(Paint.Join.ROUND);
bodyPaint.setStrokeCap(Paint.Cap.ROUND);
return bodyPaint;
}
private static Paint createGlowingPaint(Context context, float strokeWidth, float blurMaskRadius){
int glowColor = ResourcesCompat.getColor(context.getResources(), R.color.neon_glow, null);
Paint glowPaint = new Paint();
glowPaint.setAntiAlias(true);
glowPaint.setColor(glowColor);
glowPaint.setMaskFilter(new BlurMaskFilter(blurMaskRadius, BlurMaskFilter.Blur.NORMAL));
glowPaint.setStrokeWidth(strokeWidth);
glowPaint.setStyle(Paint.Style.STROKE);
glowPaint.setStrokeJoin(Paint.Join.ROUND);
glowPaint.setStrokeCap(Paint.Cap.ROUND);
return glowPaint;
}
private static float convertDpToPx(float valueDp, Context context){
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueDp, displayMetrics);
}
private void init(){
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
float bodyStrokeWidthPx = convertDpToPx(BODY_STROKE_WIDTH, getContext());
float glowStrokeWidth = bodyStrokeWidthPx * GLOWING_MULTIPLIER;
float blueRadiusPx = bodyStrokeWidthPx * BLUE_MULTIPLIER;
mPaddingPx = glowStrokeWidth / 2 + blueRadiusPx;
mBodyPaint = createBodyPaint(getContext(), bodyStrokeWidthPx);
mGlowingPaint = createGlowingPaint(getContext(), glowStrokeWidth, blueRadiusPx);
mBounds = new RectF();
mAnimator = createAnimator();
}
private Animator createAnimator(){
return AnimatorCreator.create(this);
}
}
MainActivity.java
/* Code From Learnoset - Learn Coding Online.
Download Learnoset App from PlayStore to learn coding,
projects, algorithms, error handling
*/
package com.learnoset.neonprogressbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Output

Projects with Source Code + Video Tutorials
You can download our Java and Android Studio Projects with Source Code and Video Tutorials.

Simple Music Player App for Android (Offline Version)

Simple Music Player App (Version 2) for Android (Offline Version)

Login & Register Screen UI Design - 01
If you have any Questions or Queries
You can mail us at info.learnoset@gmail.com
Follow us to learn Coding and get in touch with new Technologies.