Android Circular Determinate ProgressBar
T

4

47

I want to create a Circluar Determinate ProgressBar, the kind which shows the Progress in the center of the Bar. Is there any default way to create this, or will i have to create my own custom one.

Tiphane answered 8/10, 2012 at 6:46 Comment(2)
Most likely a duplicate of this question: #5260006Synopsize
@Synopsize no, thats about indeterminate progress bar. Very differentReluct
C
46

First add a progress_circle.xml to your res/drawable directory like this:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:drawable="@drawable/progress_circular_background"/>
<item>
    <shape
        android:innerRadiusRatio="3.4"
        android:shape="ring"
        android:thicknessRatio="6.0" >
        <gradient
            android:endColor="#ffffffff"
            android:startColor="#ffffff"
            android:type="sweep"
            android:useLevel="true" />
    </shape>
</item>
<item>
    <rotate
        android:drawable="@drawable/progress_particle"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
</item>

</layer-list>

I Googled image searched both "progress_particle.png" and "progress_circular_background.png" (with quotes) since the android default drawables for those were missing. You'll probably want to customize those but they'll do to get you started.

Then in your xml layout:

<ProgressBar
    android:id="@+id/timer_progress"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:indeterminate="false"
    android:max="60"
    android:progressDrawable="@drawable/progress_circle" />

My max is 60, since I'm using it for a seconds timer, but you might have something different.

The trick is that you need to use style="?android:attr/progressBarStyleHorizontal" even though it's a circular progress.

Cadence answered 15/10, 2012 at 23:24 Comment(7)
what type of drawable is the progress_circle.xml? The one you provided is not a complete file, it needs an upper level object to be part ofAleris
Fixed. Copy paste didn't show the enclosing tags for some reason, but they were there!Cadence
Could ring shape (not progress particle) start filling from -90 degrees (hour 12)?Homologate
I have one small question. There are drawable-ldpi,drawable-hdpi,etc. Which folder should I use for this xml?Lecher
@bagusflyer put it into folder named "drawable", xml files are dpi independent resources.Rubber
style="?android:attr/progressBarStyleHorizontal" is not necessary, android:indeterminateOnly="false" is.Heroic
Drawables can be dowloaded here: github.com/michelou/android-examples/tree/master/android-sdk/…Recall
I
65

I have written detailed example on Android circular progress bar here on my blog demonuts.com You can also fond full source code and explanation there.

Here's how I made circular progressbar with percentage inside circle in pure code without any library.

enter image description here

first create a drawable file called circular.xml

<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/secondaryProgress">
        <shape
            android:innerRadiusRatio="6"
            android:shape="ring"
            android:thicknessRatio="20.0"
            android:useLevel="true">


            <gradient
                android:centerColor="#999999"
                android:endColor="#999999"
                android:startColor="#999999"
                android:type="sweep" />
        </shape>
    </item>

    <item android:id="@android:id/progress">
        <rotate
            android:fromDegrees="270"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="270">

            <shape
                android:innerRadiusRatio="6"
                android:shape="ring"
                android:thicknessRatio="20.0"
                android:useLevel="true">


                <rotate
                    android:fromDegrees="0"
                    android:pivotX="50%"
                    android:pivotY="50%"
                    android:toDegrees="360" />

                <gradient
                    android:centerColor="#00FF00"
                    android:endColor="#00FF00"
                    android:startColor="#00FF00"
                    android:type="sweep" />

            </shape>
        </rotate>
    </item>
</layer-list>

Now in your activity_main.xml add following:

  <?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
    android:background="@color/dialog"
    tools:context="com.example.parsaniahardik.progressanimation.MainActivity">

    <ProgressBar

        android:id="@+id/circularProgressbar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:indeterminate="false"
        android:max="100"
        android:progress="50"
        android:layout_centerInParent="true"
        android:progressDrawable="@drawable/circular"
        android:secondaryProgress="100"
        />

    <ImageView
        android:layout_width="90dp"
        android:layout_height="90dp"
        android:background="@drawable/whitecircle"
        android:layout_centerInParent="true"/>

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

</RelativeLayout>

In activity_main.xml I have used one circular image with white background to show white background around percentage. Here is the image:

enter image description here

You can change color of this image to set custom color around percentage text.

Now finally add following code to MainActivity.java :

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

public class MainActivity extends AppCompatActivity {

    int pStatus = 0;
    private Handler handler = new Handler();
    TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Resources res = getResources();
        Drawable drawable = res.getDrawable(R.drawable.circular);
        final ProgressBar mProgress = (ProgressBar) findViewById(R.id.circularProgressbar);
        mProgress.setProgress(0);   // Main Progress
        mProgress.setSecondaryProgress(100); // Secondary Progress
        mProgress.setMax(100); // Maximum Progress
        mProgress.setProgressDrawable(drawable);

      /*  ObjectAnimator animation = ObjectAnimator.ofInt(mProgress, "progress", 0, 100);
        animation.setDuration(50000);
        animation.setInterpolator(new DecelerateInterpolator());
        animation.start();*/

        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
                            mProgress.setProgress(pStatus);
                            tv.setText(pStatus + "%");

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

If you want to make horizontal progressbar, follow this link, it has many valuable examples with source code:
http://www.skholingua.com/android-basic/user-interface/form-widgets/progressbar

Izzo answered 11/5, 2016 at 11:4 Comment(4)
why is it so much of extra spacing outside progressbar? How do I reduce itTicking
changed android:innerRadiusRatio="2.5" from 6 to 2.5Ticking
changed the from android:innerRadiusRatio="6" to android:innerRadiusRatio="2.35" it's perfect with almost no extra spaceHigley
top, great solution!Tracheostomy
C
46

First add a progress_circle.xml to your res/drawable directory like this:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:drawable="@drawable/progress_circular_background"/>
<item>
    <shape
        android:innerRadiusRatio="3.4"
        android:shape="ring"
        android:thicknessRatio="6.0" >
        <gradient
            android:endColor="#ffffffff"
            android:startColor="#ffffff"
            android:type="sweep"
            android:useLevel="true" />
    </shape>
</item>
<item>
    <rotate
        android:drawable="@drawable/progress_particle"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
</item>

</layer-list>

I Googled image searched both "progress_particle.png" and "progress_circular_background.png" (with quotes) since the android default drawables for those were missing. You'll probably want to customize those but they'll do to get you started.

Then in your xml layout:

<ProgressBar
    android:id="@+id/timer_progress"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:indeterminate="false"
    android:max="60"
    android:progressDrawable="@drawable/progress_circle" />

My max is 60, since I'm using it for a seconds timer, but you might have something different.

The trick is that you need to use style="?android:attr/progressBarStyleHorizontal" even though it's a circular progress.

Cadence answered 15/10, 2012 at 23:24 Comment(7)
what type of drawable is the progress_circle.xml? The one you provided is not a complete file, it needs an upper level object to be part ofAleris
Fixed. Copy paste didn't show the enclosing tags for some reason, but they were there!Cadence
Could ring shape (not progress particle) start filling from -90 degrees (hour 12)?Homologate
I have one small question. There are drawable-ldpi,drawable-hdpi,etc. Which folder should I use for this xml?Lecher
@bagusflyer put it into folder named "drawable", xml files are dpi independent resources.Rubber
style="?android:attr/progressBarStyleHorizontal" is not necessary, android:indeterminateOnly="false" is.Heroic
Drawables can be dowloaded here: github.com/michelou/android-examples/tree/master/android-sdk/…Recall
O
10

An example of a determinate circular progress indicator

<com.google.android.material.progressindicator.CircularProgressIndicator
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:progress="75"
  app:indicatorColor="#FF0000"
  app:indicatorSize="100dp"
  app:trackColor="#D3D3D3"
  app:trackThickness="10dp" />

References

Obovate answered 14/6, 2021 at 14:14 Comment(1)
This answer saved my day! Thanks a bunch!!Pinafore
A
9

For the determinate part of your question, material design library now supports determinate circular progress bars:

<com.google.android.material.progressindicator.CircularProgressIndicator
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

For more info refer here.

Other answers may help on how to insert the progress label in the center.

Alrick answered 8/1, 2021 at 9:25 Comment(4)
Anybody knows how to implement it... The documentation doesn't help. Just can't get it to work....Coffle
@whoadityanawandar I've not used these myself but if by implementing you mean make the progress bar determinate in code, the documentation suggests this: int progress = getLoadingProgress() indicator.setProgressCompat(progress, true)Alrick
Thanks, although this still looks incomplete, I mean how do you set the timer for it and all...Coffle
Thank buddy :D I am asking myself why we need to custom a very common element like progress barBirthstone

© 2022 - 2024 — McMap. All rights reserved.