4

Hi I want to make a Pie Progress bar in android like the attached image..

enter image description here

I have go through the following code but no gain.enter link description here

So i decided to write my own ProgressBarView. Here is my sample code ..

public class PieProgressView extends View {

private float mProgress;

private int MAX_ANGLE = 360;


public PieProgressView(Context context) {
    super(context);
}

public PieProgressView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public PieProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}



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

}

public void setProgress(int progress){
    mProgress = (float) ((float)progress*3.6);
    invalidate();
}

private void drawOval(Canvas canvas){
    canvas.drawColor(Color.CYAN);
    Paint paint = new Paint();
    // smooths
    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.RED);
    RectF oval2 = new RectF(50, 50, 500, 500);
    canvas.drawOval(oval2, paint);// opacity

    Paint p = new Paint();
    p.setColor(Color.BLACK);
    canvas.drawArc(oval2, 270, mProgress, true, p);
    System.out.println("drawOval Progress == "+mProgress);


    //p.setAlpha(0x80); //
}

}

and the activity class from i call this..

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

    button = (Button)findViewById(R.id.button);
    pieProgressView = (PieProgressView)findViewById(R.id.pieprogress);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fillProgress();
        }
    });

}

private void fillProgress(){
    for(int i=0;i<100 ; i++) {

            pieProgressView.setProgress(i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();

        }
    }
}

Now during this for loop there is no progress shown but after completion of for loop it will shows the progress bar like in attached image showing a black progress.

can anyone tell me what the wrong with this code. Why this code not doing a continuous update ?

Community
  • 1
  • 1
nitin tyagi
  • 1,176
  • 1
  • 19
  • 52
  • Does `setProgress( )` work properly on its own without the loop ? – An SO User Jan 20 '16 at 06:49
  • @LittleChild yes it works without loop but when i run the loop then it will update only after completion of loop. Actually in my application i am downloading some file from server and i want to show the progress dialog in this fashion . So i use for loop for continuously update the view. – nitin tyagi Jan 20 '16 at 06:59

3 Answers3

5

I achieve it like

<ProgressBar
        android:id="@+id/pr_progress_in_circle"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:indeterminate="false"
        android:max="100"
        android:progress="60"
        android:progressDrawable="@drawable/progress"
        android:rotation="-90" />

where progress.xml

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


    <item
        android:bottom="@dimen/dimen_2"
        android:left="@dimen/dimen_2"
        android:right="@dimen/dimen_2"
        android:top="@dimen/dimen_2">
        <shape android:shape="oval">
            <solid android:color="@color/grey_lighter" />
            <stroke android:color="@android:color/transparent" />
        </shape>
    </item>
    <item>
        <shape
            android:innerRadiusRatio="100"
            android:shape="ring"
            android:thicknessRatio="2.5"
            android:useLevel="true">
            <gradient
                android:centerColor="@color/orange_above_avg"
                android:endColor="@color/orange_above_avg"
                android:startColor="@color/orange_above_avg"
                android:type="sweep"
                android:useLevel="false" />
        </shape>
    </item>


</layer-list>

and you can test it by

        mProgressBar.setMax(totalQuestions);
        mProgressBar.setProgress(correctQuestion);

enter image description here

or go for this library

Zar E Ahmer
  • 33,936
  • 20
  • 234
  • 300
0

Thread.sleep( ) is causing the UI thread to block and hence you see the "filled" pie chart when the thread wakes up. I changed the code to use a CountDownTimer instead and it works like a charm. Here's the code:

public class MainActivity extends AppCompatActivity {
    PieProgressView pie;
    CountDownTimer timer;
    int progress = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pie = (PieProgressView) findViewById(R.id.pie);
        scheduleNextTimer();
    }

    private CountDownTimer getTimer(){
        return new CountDownTimer(1000,1000) {
            @Override
            public void onTick(long millisUntilFinished) {

            }

            @Override
            public void onFinish() {
                Log.d("PROG",progress + "");
                pie.setProgress( progress++ );
                scheduleNextTimer();
            }
        };
    }

    private void scheduleNextTimer(){
        if( progress < 100 ){
            timer = getTimer();
            timer.start();
        }
    }
}
An SO User
  • 24,612
  • 35
  • 133
  • 221
0

Try using this code snippet as progress drawable :

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

    <item
        android:id="@android:id/background"
        android:bottom="3dp"
        android:left="3dp"
        android:right="3dp"
        android:top="3dp">
        <shape android:shape="oval">
            <solid android:color="@color/transparent" />
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <shape
            android:innerRadiusRatio="100"
            android:shape="ring"
            android:thicknessRatio="2.5"
            android:useLevel="true">
            <solid
                android:color="@color/dark_black_half_transparent"
                android:useLevel="false" />
        </shape>
    </item>

</layer-list>

You can play with the progress being clockwise or anti-clockwise by this change :

  android:scaleX="-1"

Your progressbar in your layout should be like this :

 <ProgressBar
        android:id="@+id/progressbar"
        style="?android:progressBarStyleHorizontal"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:progress="@{viewModel.progressUpload}"
        android:max="100"
        android:rotation="90"
        android:scaleX="-1"
        android:progressDrawable="@drawable/custom_progressbar_drawable"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
Rami
  • 158
  • 1
  • 8