Headertab

Drop Down MenusCSS Drop Down MenuPure CSS Dropdown Menu

Thursday 18 February 2016

CircularProgressbar sample

Hello gyes
Today we are learn very interesting component like animated CircularProgressbar so are you ready to learn how to create  ???
So lets start.

  See live sample                                                                                   




Create a new project in android studio and follow give all instructions.

Create a new java class by name CircularProgressBar.java

CircularProgressBar.java


package com.samset.circularprogressbar.custom_views.circularprogressbar;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ProgressBar;

import com.samset.circularprogressbar.R;


public class CircularProgressBar extends ProgressBar{
private static final String TAG = "CircularProgressBar";

private static final int STROKE_WIDTH = 20;

private String mTitle = "";
private String mSubTitle = "";
private int Titlesize = 0;

private int mStrokeWidth = STROKE_WIDTH;

private final RectF mCircleBounds = new RectF();

private final Paint mProgressColorPaint = new Paint();
private final Paint mBackgroundColorPaint = new Paint();
private final Paint mTitlePaint = new Paint();
private final Paint mSubtitlePaint = new Paint();

private boolean mHasShadow = true;
private int mShadowColor = Color.BLACK;

public interface ProgressAnimationListener{
public void onAnimationStart();
public void onAnimationFinish();
public void onAnimationProgress(int progress);
}

public CircularProgressBar(Context context) {
super(context);
init(null, 0);
}

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

public CircularProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}

public void init(AttributeSet attrs, int style){
//so that shadow shows up properly for lines and arcs
setLayerType(View.LAYER_TYPE_SOFTWARE, null);

TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.CircularProgressBar, style, 0);

String color;
Resources res = getResources();

this.mHasShadow = a.getBoolean(R.styleable.CircularProgressBar_cpb_hasShadow, true);

color = a.getString(R.styleable.CircularProgressBar_cpb_progressColor);
if(color==null)
mProgressColorPaint.setColor(res.getColor(R.color.circular_progress_default_progress));
else
mProgressColorPaint
.setColor(Color.parseColor(color));

color = a.getString(R.styleable.CircularProgressBar_cpb_backgroundColor);
if(color==null)
mBackgroundColorPaint.setColor(res.getColor(R.color.circular_progress_default_background));
else
mBackgroundColorPaint
.setColor(Color.parseColor(color));

color = a.getString(R.styleable.CircularProgressBar_cpb_titleColor);
if(color==null)
mTitlePaint.setColor(res.getColor(R.color.circular_progress_default_title));
else
mTitlePaint
.setColor(Color.parseColor(color));

color = a.getString(R.styleable.CircularProgressBar_cpb_subtitleColor);
if(color==null)
mSubtitlePaint.setColor(res.getColor(R.color.circular_progress_default_subtitle));
else
mSubtitlePaint
.setColor(Color.parseColor(color));


String t = a.getString(R.styleable.CircularProgressBar_cpb_title);
if(t!=null)
mTitle = t;

t = a.getString(R.styleable.CircularProgressBar_cpb_subtitle);
if(t!=null)
mSubTitle = t;

mStrokeWidth = a.getInt(R.styleable.CircularProgressBar_cpb_strokeWidth, STROKE_WIDTH);

a.recycle();


mProgressColorPaint.setAntiAlias(true);
mProgressColorPaint.setStyle(Style.STROKE);
mProgressColorPaint.setStrokeWidth(mStrokeWidth);

mBackgroundColorPaint.setAntiAlias(true);
mBackgroundColorPaint.setStyle(Style.STROKE);
mBackgroundColorPaint.setStrokeWidth(mStrokeWidth);

if (Titlesize==0)
{
mTitlePaint.setTextSize(40);
}else
{
mTitlePaint.setTextSize(Titlesize);
}
mTitlePaint.setStyle(Style.FILL);
mTitlePaint.setAntiAlias(true);
mTitlePaint.setTypeface(Typeface.create("Roboto-Thin", Typeface.NORMAL));
mTitlePaint.setShadowLayer(0.1f, 0, 1, Color.GRAY);

mSubtitlePaint.setTextSize(20);
mSubtitlePaint.setStyle(Style.FILL);
mSubtitlePaint.setAntiAlias(true);
mSubtitlePaint.setTypeface(Typeface.create("Roboto-Thin", Typeface.BOLD));
// mSubtitlePaint.setShadowLayer(0.1f, 0, 1, Color.GRAY);
}

@Override
protected synchronized void onDraw(Canvas canvas) {
canvas.drawArc(mCircleBounds, 0, 360 , false, mBackgroundColorPaint);

int prog = getProgress();
float scale = getMax() > 0 ? (float)prog/getMax() *360: 0;

if(mHasShadow)
mProgressColorPaint.setShadowLayer( 3, 0, 1, mShadowColor);
canvas.drawArc(mCircleBounds, 270, scale, false, mProgressColorPaint);


if(!TextUtils.isEmpty(mTitle)){
int xPos =  (int)(getMeasuredWidth()/2 - mTitlePaint.measureText(mTitle) / 2);
int yPos = (int) (getMeasuredHeight()/2);

float titleHeight = Math.abs(mTitlePaint.descent() + mTitlePaint.ascent());
if(TextUtils.isEmpty(mSubTitle)){
yPos += titleHeight/2;
}
canvas.drawText(mTitle, xPos, yPos, mTitlePaint);

yPos += titleHeight;
xPos = (int)(getMeasuredWidth()/2 - mSubtitlePaint.measureText(mSubTitle) / 2);

canvas.drawText(mSubTitle, xPos, yPos, mSubtitlePaint);
}

super.onDraw(canvas);
}

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
final int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int min = Math.min(width, height);
setMeasuredDimension(min + 2 * STROKE_WIDTH, min + 2 * STROKE_WIDTH);

mCircleBounds.set(STROKE_WIDTH, STROKE_WIDTH, min + STROKE_WIDTH, min + STROKE_WIDTH);
}

@Override
public synchronized void setProgress(int progress) {
super.setProgress(progress);

// the setProgress super will not change the details of the progress bar
// anymore so we need to force an update to redraw the progress bar
invalidate();
}

public void animateProgressTo(final int start, final int end, final ProgressAnimationListener listener){
if(start!=0)
setProgress(start);

final ObjectAnimator progressBarAnimator = ObjectAnimator.ofFloat(this, "animateProgress", start, end);
progressBarAnimator.setDuration(1500);
// progressBarAnimator.setInterpolator(new AnticipateOvershootInterpolator(2f, 1.5f));
progressBarAnimator.setInterpolator(new LinearInterpolator());

progressBarAnimator.addListener(new AnimatorListener() {
@Override
public void onAnimationCancel(final Animator animation) {
}

@Override
public void onAnimationEnd(final Animator animation) {
CircularProgressBar.this.setProgress(end);
if (listener != null)
listener.onAnimationFinish();
}

@Override
public void onAnimationRepeat(final Animator animation) {
}

@Override
public void onAnimationStart(final Animator animation) {
if (listener != null)
listener.onAnimationStart();
}
});

progressBarAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(final ValueAnimator animation) {
int progress = ((Float) animation.getAnimatedValue()).intValue();
if(progress!=CircularProgressBar.this.getProgress()){
Log.d(TAG, progress + "");
CircularProgressBar.this.setProgress(progress);
if(listener!=null)
listener.onAnimationProgress(progress);
}
}
});
progressBarAnimator.start();
}

public synchronized void setTitle(String title){
this.mTitle = title;
invalidate();
}
public synchronized void setTitleSize(int size){
this.Titlesize = size;
invalidate();
}


public synchronized void setSubTitle(String subtitle){
this.mSubTitle = subtitle;
invalidate();
}

public synchronized void setSubTitleColor(int color){
mSubtitlePaint.setColor(color);
invalidate();
}

public synchronized void setTitleColor(int color){
mTitlePaint.setColor(color);
invalidate();
}
public synchronized void setProgressbarColor(int color){
mProgressColorPaint.setColor(color);
invalidate();
}
public synchronized void setProgressbarBackgroundColor(int color){
mBackgroundColorPaint.setColor(color);
invalidate();
}

public synchronized void setHasShadow(boolean flag){
this.mHasShadow = flag;
invalidate();
}

public synchronized void setShadow(int color){
this.mShadowColor = color;
invalidate();
}



public String getTitle(){
return mTitle;
}

public boolean getHasShadow(){
return mHasShadow;
}
}


Go to res folder and go to values folder and create a resource file by name attrs.xml

attrs.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircularProgressBar">
        <attr name="cpb_hasShadow" format="boolean"/>
        <attr name="cpb_progressColor" format="string"/>
        <attr name="cpb_backgroundColor" format="string"/>
        <attr name="cpb_title" format="string"/>
        <attr name="cpb_titleColor" format="string"/>
        <attr name="cpb_subtitle" format="string"/>
        <attr name="cpb_subtitleColor" format="string"/>
        <attr name="cpb_strokeWidth" format="integer"/>
    </declare-styleable>
</resources>

Create a color file a same folder

color.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="pb_background">#09cbd0</color>

    <!--Circularprogressbar start-->
   
<color name="circular_progress_default_progress">#157e78</color>
    <color name="circular_progress_default_background">#787878</color>
    <color name="circular_progress_default_title">#09cbd0</color>
    <color name="circular_progress_default_subtitle">#D1D1D1</color>
    <!--Circularprogressbar end-->
</resources>


Now you open style resource file and paste below code carefully

style.xml


<resources>
    <style name="AppTheme" parent="Theme.AppCompat">
        <!-- Customize your theme here. -->
   
</style>
    <!-- Base application theme. -->
   
<style name="Theme.AppCompat" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
       
<item name="android:windowContentOverlay">@null</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowIsTranslucent">true</item>
    </style>
    <!-- Circularprogressbar start-->
   
<style name="Widget"></style>
    <style name="Widget.ProgressBar.CircularProgressBar" parent="Widget">
        <item name="android:indeterminateOnly">false</item>
        <item name="android:adjustViewBounds">true</item>
        <item name="cpb_progressColor">@color/circular_progress_default_progress</item>
        <item name="cpb_hasShadow">true</item>
        <item name="cpb_strokeWidth">20</item>
        <item name="cpb_titleColor">@color/circular_progress_default_title</item>
        <item name="cpb_subtitleColor">@color/circular_progress_default_subtitle</item>
    </style>

    <style name="Widget.ProgressBar.Holo.CircularProgressBar" parent="Widget.ProgressBar.CircularProgressBar">
        <item name="cpb_hasShadow">true</item>
        <item name="cpb_strokeWidth">20</item>
    </style>
    <!-- for your custom use item-->
   
<style name="Widget.ProgressBar.Holo.CircularPro1" parent="Widget.ProgressBar.CircularProgressBar">
        <item name="cpb_hasShadow">false</item>
        <item name="cpb_strokeWidth">5</item>
    </style>
    <style name="Widget.ProgressBar.Holo.CircularPro2" parent="Widget.ProgressBar.CircularProgressBar">
        <item name="cpb_hasShadow">true</item>
        <item name="cpb_strokeWidth">10</item>
    </style>
    <!-- Circularprogressbar end-->
</resources>


Now you create drwable file in drawable folder by name

timer_shape.xml


<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- "background shadow" -->
   
<item>
        <shape  android:shape="oval" >
            <solid android:color="#e5e5e5" />

            <size
                android:height="95dp"
                android:width="95dp"
/>
        </shape>
    </item>
    <item android:bottom="3px"
        android:left="3px"
        android:right="3px"
        android:top="3px"
>
        <shape  android:shape="oval" >
            <solid android:color="#fff" />

            <size
                android:height="50dp"
                android:width="50dp"
/>
        </shape>
    </item>

</layer-list>

And last you go to activity_main.xml and paste code

activity_main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:circular="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="#3d3d3d"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
>

        <com.samset.circularprogressbar.custom_views.circularprogressbar.CircularProgressBar
            android:id="@+id/circularprogressbar1"
            style="@style/Widget.ProgressBar.Holo.CircularProgressBar"
            android:layout_width="120dip"
            android:layout_height="120dip"
            android:layout_marginTop="10dip"
            circular:cpb_subtitle="subtitle"
            circular:cpb_title="Title"
/>

        <com.samset.circularprogressbar.custom_views.circularprogressbar.CircularProgressBar
            android:id="@+id/circularprogressbar2"
            style="@style/Widget.ProgressBar.Holo.CircularProgressBar"
            android:layout_width="110dip"
            android:layout_height="110dip"
            android:layout_marginTop="10dip"
            circular:cpb_subtitle="subtitle"
            circular:cpb_title="Title"
/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
>

        <com.samset.circularprogressbar.custom_views.circularprogressbar.CircularProgressBar
            android:id="@+id/circularprogressbar3"
            style="@style/Widget.ProgressBar.CircularProgressBar"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginTop="10dip"
            circular:cpb_subtitle="subtitle"
            circular:cpb_title="Title"
/>

        <com.samset.circularprogressbar.custom_views.circularprogressbar.CircularProgressBar
            android:id="@+id/circularprogressbar4"
            style="@style/Widget.ProgressBar.CircularProgressBar"
            android:layout_width="100dip"
            android:layout_height="100dip"
            android:layout_marginTop="10dip"
            circular:cpb_subtitle="subtitle"
            circular:cpb_title="Title"
/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
>

        <com.samset.circularprogressbar.custom_views.circularprogressbar.CircularProgressBar
            android:id="@+id/circularprogressbar5"
            style="@style/Widget.ProgressBar.Holo.CircularPro1"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginTop="10dip"
            android:layout_weight="1"
            circular:cpb_subtitle="subtitle"
            circular:cpb_title="Title"
/>


    </LinearLayout>

    <!-- If you want to create some custom views then see code-->
   
<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
>

        <com.samset.circularprogressbar.custom_views.circularprogressbar.CircularProgressBar
            android:id="@+id/circularprogressbar6"
            style="@style/Widget.ProgressBar.Holo.CircularPro2"
            android:layout_width="100dip"
            android:layout_height="100dip"
            android:layout_marginTop="10dip"
            android:layout_centerInParent="true"
            android:layout_weight="1"
            circular:cpb_subtitle="subtitle"
            circular:cpb_title="Title"
/>

        <RelativeLayout
            android:id="@+id/layoutHQ"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:background="@drawable/timer_shape"
            android:gravity="center"
>

            <TextView
                android:id="@+id/txtresult"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:padding="5dp"
                android:text="0"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@color/colorAccent"
                android:textStyle="bold"
/>

        </RelativeLayout>
    </RelativeLayout>
</LinearLayout>



MainActivity.java



/*
 * Copyright (C) 2016 Sanjay singh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.samset.circularprogressbar;

import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.samset.circularprogressbar.custom_views.circularprogressbar.CircularProgressBar;

public class MainActivity extends AppCompatActivity {
    private CircularProgressBar c1;
    private CircularProgressBar c2;
    private CircularProgressBar c3;
    private CircularProgressBar c4;
    private CircularProgressBar c5;
    private CircularProgressBar c6;

    private TextView tv_result;
    private MyCountDownTimer countDownTimer;
    private int progress = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_result= (TextView) findViewById(R.id.txtresult);
        c1();
        c2();
        c3();
        c4();
        c5();
        c6();

        countDownTimer = new MyCountDownTimer(10000, 100);
        countDownTimer.start();

    }

    private void c1() {
        c1 = (CircularProgressBar) findViewById(R.id.circularprogressbar1);
        c1.setProgress(45);

    }

    private void c2() {
        c2 = (CircularProgressBar) findViewById(R.id.circularprogressbar2);
        c2.animateProgressTo(0, 77, new CircularProgressBar.ProgressAnimationListener() {
            @Override
            public void onAnimationStart() {

            }

            @Override
            public void onAnimationFinish() {
                c2.setSubTitle("done");
            }

            @Override
            public void onAnimationProgress(int progress) {
                c2.setTitle(progress + "%");
            }
        });

    }

    private void c3() {
        c3 = (CircularProgressBar) findViewById(R.id.circularprogressbar3);
        c3.setTitle("Sam");
        c3.setSubTitle("set");
        c2.setProgress(34);
    }

    private void c4() {
        c4 = (CircularProgressBar) findViewById(R.id.circularprogressbar4);
        c4.setProgress(58);
    }

    private void c5() {
        c5 = (CircularProgressBar) findViewById(R.id.circularprogressbar5);
        c4.setProgress(15);
    }

    private void c6() {
        c6 = (CircularProgressBar) findViewById(R.id.circularprogressbar6);
    }

    public class MyCountDownTimer extends CountDownTimer {

        public MyCountDownTimer(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }

        @Override
        public void onTick(long millisUntilFinished) {


            progress = (int) (millisUntilFinished / 100);
            //You can change progressbar background color and front color
           
c6.setProgressbarBackgroundColor(getResources().getColor(R.color.pb_background));
            c6.setProgressbarColor(getResources().getColor(R.color.colorAccent));

            c6.setProgress(progress);
            tv_result.setText("" + progress);
        }

        @Override
        public void onFinish() {
            //onfinish you write your code
       
}
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        countDownTimer.cancel();
    }
}

See build.gradle file preview


apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

   
defaultConfig {
        applicationId "com.samset.circularprogressbar"
       
minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
   
}
    buildTypes {
        release {
            minifyEnabled false
           
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
       
}
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
   
compile 'com.android.support:appcompat-v7:23.1.1'
}


Done
I hope this blog helps you.
If this blog helps you then do not forget  to like and comment.

You want to download full source code go below link...

https://github.com/SamsetDev/CircularProgressbar_Example/tree/master


Enjoy and play with code.


2 comments: