0

I want to create a custom progress bar for my Android application. I'd like to get something like that: enter image description here

I've created the following code to create a two colors progress bar:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <gradient
                android:startColor="#385B68"
                android:centerColor="#385B68"
                android:centerY="1.0"
                android:endColor="#385B68"
                android:angle="270" />
        </shape>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <gradient
                    android:startColor="#65B4D4"
                    android:centerColor="#65B4D4"
                    android:centerY="1.0"
                    android:endColor="#65B4D4"
                    android:angle="270" />
            </shape>
        </clip>
    </item>

</layer-list>

But I'd like to know how I could add the separators every 10% or even every 20%. Is there a special way to achieve that ?

Thanks for your precious help.

Manitoba
  • 8,522
  • 11
  • 60
  • 122

1 Answers1

0

In order to create such a custom progress bar. Create a new class:

import java.util.ArrayList;
import java.util.List;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;

public class ProgressBarDrawable extends Drawable
{
    private int parts = 10;

    private Paint paint = null;
    private int fillColor = Color.parseColor("#2D6EB9");
    private int emptyColor = Color.parseColor("#233952");
    private int separatorColor = Color.parseColor("#FFFFFF");
    private RectF rectFill = null;
    private RectF rectEmpty = null;
    private List<RectF> separators = null;

    public ProgressBarDrawable(int parts)
    {
        this.parts = parts;
        this.paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        this.separators = new ArrayList<RectF>();
    }

    @Override
    protected boolean onLevelChange(int level)
    {
        invalidateSelf();
        return true;
    }

    @Override
    public void draw(Canvas canvas)
    {
        // Calculate values
        Rect b = getBounds();
        float width = b.width();
        float height = b.height();

        int spaceFilled = (int)(getLevel() * width / 10000);
        this.rectFill = new RectF(0, 0, spaceFilled, height);
        this.rectEmpty = new RectF(spaceFilled, 0, width, height);

        int spaceBetween = (int)(width / 100);
        int widthPart = (int)(width / this.parts - (int)(0.9 * spaceBetween));
        int startX = widthPart;
        for (int i=0; i<this.parts - 1; i++)
        {
            this.separators.add( new RectF(startX, 0, startX + spaceBetween, height) );
            startX += spaceBetween + widthPart;
        }


        // Foreground
        this.paint.setColor(this.fillColor);
        canvas.drawRect(this.rectFill, this.paint);

        // Background
        this.paint.setColor(this.emptyColor);
        canvas.drawRect(this.rectEmpty, this.paint);

        // Separator
        this.paint.setColor(this.separatorColor);
        for (RectF separator : this.separators)
        {
            canvas.drawRect(separator, this.paint);
        }
    }

    @Override
    public void setAlpha(int alpha)
    {
    }

    @Override
    public void setColorFilter(ColorFilter cf)
    {
    }

    @Override
    public int getOpacity()
    {
        return PixelFormat.TRANSLUCENT;
    }
}

And then, where you want to apply the custom theme, use this code: (10 is the number of parts).

ProgressBarDrawable bgProgress= new ProgressBarDrawable(10);
progressbar.setProgressDrawable(bgProgress);
Manitoba
  • 8,522
  • 11
  • 60
  • 122
  • It has strange behavior !! If i do progressbar.setProgress(20) it does not work but all other values except 20 are working just fine. Could you please let me know if something can be done for this? – Chaitanya Chandurkar Jun 14 '14 at 09:05
  • Got the answer. If you declare progress of ProgressBar in XML and try to re-assign same value of progress in Java it will just make the ProgressBar blank. It will set progress to 0. Very Strange !! Please look into it – Chaitanya Chandurkar Jun 14 '14 at 09:09
  • Also could you please tell me what changes needs to be done if I want corner radius of every part? – Chaitanya Chandurkar Jun 14 '14 at 09:28
  • Hello, as I draw the separators AFTER the progress and the background, it's impossible. The solution would be to draw each rectangle separately and apply a radius on each one (With a `GradientDrawable` for example http://stackoverflow.com/a/18938616/1295422). – Manitoba Jun 16 '14 at 07:53