Wednesday 22 August 2018

CircularProgressBar - Android

Custom Circular Progress Bar

package com.example.macbook.spinner;

import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    int pStatus = 0;
    private Handler handler = new Handler();
    TextView tv;
    CircularProgressBar circularProgressBar;
    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        circularProgressBar = (CircularProgressBar) findViewById(R.id.circularProgress);
        circularProgressBar.setProgressColor(Color.BLUE);

        tv = (TextView) findViewById(R.id.tv);
        new Thread(new Runnable() {

            @Override            public void run() {
                // TODO Auto-generated method stub                while (pStatus < 100) {
                    pStatus += 1;

                    handler.post(new Runnable() {

                        @Override                        public void run() {
                            // TODO Auto-generated method stub                            circularProgressBar.setProgress(pStatus);
                            if(pStatus>70){
                                circularProgressBar.setProgressColor(Color.RED);
                            }else{
                                circularProgressBar.setProgressColor(Color.BLUE);
                            }
                            tv.setText(pStatus + "%");

                        }
                    });
                    try {
                        // Sleep for 200 milliseconds.                        // Just to display the progress slowly                        Thread.sleep(30); //thread will take approx 1.5 seconds to finish                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout 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">

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:tools="http://schemas.android.com/tools"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="#FFFFFF"        tools:context="com.example.parsaniahardik.progressanimation.MainActivity">

        <com.example.macbook.spinner.CircularProgressBar            android:id="@+id/circularProgress"            android:layout_width="180dp"            android:layout_marginLeft="10dp"            android:layout_centerInParent="true"            android:layout_height="180dp"            />

        <TextView            android:visibility="visible"            android:id="@+id/tv"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:gravity="center"            android:text="25%"            android:layout_centerInParent="true"            android:textColor="@color/colorPrimaryDark"            android:textSize="20sp" />

    </RelativeLayout>



</android.support.constraint.ConstraintLayout>

CircularProgressBar.java

package com.example.macbook.spinner;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;


public class CircularProgressBar extends View {

    private int mViewWidth;
    private int mViewHeight;

    private final float mStartAngle = -90;      // Always start from top (default is: "3 o'clock on a watch.")    private float mSweepAngle = 0;              // How long to sweep from mStartAngle    private float mSweepFinisher = 0;
    private float mMaxSweepAngle = 360;         // Max degrees to sweep = full circle    private int mStrokeWidth = 40;              // Width of outline    private int mAnimationDuration = 400;       // Animation duration for progress change    private int mMaxProgress = 100;             // Max progress to use    private boolean mDrawText = true;           // Set to true if progress text should be drawn    private boolean mRoundedCorners = true;     // Set to true if rounded corners should be applied to outline ends    private int mProgressColor = Color.BLACK;   // Outline color    private int mTextColor = Color.BLACK;       // Progress text color
    private final Paint mPaint;                 // Allocate paint outside onDraw to avoid unnecessary object creation
    public CircularProgressBar(Context context) {
        this(context, null);
    }

    public CircularProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircularProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

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

//        if (mDrawText) {//            drawText(canvas);//        }    }

    private void initMeasurments() {
        mViewWidth = getWidth();
        mViewHeight = getHeight();
    }

    private void drawOutlineArc(Canvas canvas) {

        final int diameter = Math.min(mViewWidth, mViewHeight) - (mStrokeWidth);

        //Draw background        mPaint.setColor(Color.GRAY);
        final RectF outerOval = new RectF(mStrokeWidth, mStrokeWidth, diameter, diameter);
        canvas.drawArc(outerOval, -90, 360, false, mPaint);

        mPaint.setColor(mProgressColor);
        mPaint.setStrokeWidth(mStrokeWidth);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeCap(Paint.Cap.BUTT);
        mPaint.setStyle(Paint.Style.STROKE);
        if(mSweepAngle!=360) {
            canvas.drawArc(outerOval, mStartAngle, mSweepAngle - 5, false, mPaint);
        }else{
            canvas.drawArc(outerOval, mStartAngle, mSweepAngle, false, mPaint);
        }
            mPaint.setColor(mProgressColor);
            mPaint.setStrokeWidth(mStrokeWidth);
            mPaint.setAntiAlias(true);
            mPaint.setStrokeCap(mRoundedCorners ? Paint.Cap.ROUND : Paint.Cap.BUTT);
            mPaint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(outerOval, mStartAngle+5, mSweepAngle-8, false, mPaint);

    }

//    private void drawText(Canvas canvas) {//        mPaint.setTextSize(Math.min(mViewWidth, mViewHeight) / 5f);//        mPaint.setTextAlign(Paint.Align.CENTER);//        mPaint.setStrokeWidth(0);//        mPaint.setColor(mTextColor);////        // Center text//        int xPos = (canvas.getWidth() / 2);//        int yPos = (int) ((canvas.getHeight() / 2) - ((mPaint.descent() + mPaint.ascent()) / 2)) ;////        canvas.drawText(calcProgressFromSweepAngle(mSweepAngle) + "%", xPos, yPos, mPaint);//    }
    private float calcSweepAngleFromProgress(int progress) {
        return (mMaxSweepAngle / mMaxProgress) * progress;
    }

    private int calcProgressFromSweepAngle(float sweepAngle) {
        return (int) ((sweepAngle * mMaxProgress) / mMaxSweepAngle);
    }

    /**     * Set progress of the circular progress bar.     * @param progress progress between 0 and 100.     */    public void setProgress(int progress) {
        ValueAnimator animator = ValueAnimator.ofFloat(mSweepAngle, calcSweepAngleFromProgress(progress));
        animator.setInterpolator(new DecelerateInterpolator());
        animator.setDuration(mAnimationDuration);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mSweepAngle = (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        animator.start();
    }

    public void setProgressColor(int color) {
        mProgressColor = color;
        invalidate();
    }

    public void setProgressWidth(int width) {
        mStrokeWidth = width;
        invalidate();
    }

    public void setTextColor(int color) {
        mTextColor = color;
        invalidate();
    }

    public void showProgressText(boolean show) {
        mDrawText = show;
        invalidate();
    }

    /**     * Toggle this if you don't want rounded corners on progress bar.     * Default is true.     * @param roundedCorners true if you want rounded corners of false otherwise.     */    public void useRoundedCorners(boolean roundedCorners) {
        mRoundedCorners = roundedCorners;
        invalidate();
    }
}

OutPut