Darko Petkovski Darko Petkovski - 1 year ago 82
Android Question

Horizontal progressbar add circle indicators

Im trying to create a custom horizontal progressBar that will have certain amount of circle indicators in it, like this one:
enter image description here

Can anyone tell me how can I achieve this effect(adding of the circle indicators)?

Answer Source

Presuming your circle indicators are all at a set interval (the same distance apart) the following seems to me to be the most logical solution

  1. Create a custom view
  2. Extend ProgressBar so that you inherit all of the current functionality and don't have to make your own setProgress methods (etc.)
  3. Create a custom property 'tickInterval' (which I would suggest as being % points of value rather than in dp of view, but you could use either)
  4. Create an XML file for the custom attr if you want to use your view from xml
  5. When the view is drawn, paint your indicator at every interval

You might need to adjust padding in your view to make sure there is room for your circles. Below is a brief idea of what you need:

public class TickedProgressBarView extends ProgressBar {

    private static final float DEFAULT_INTERVAL = 25f;
    private float INDICATOR_RADIUS;
    private Paint mTickPaint;
    private float mInterval; //%

    public TickedProgressBarView(Context context) {
        initPainters(context, null); //because draw is called a lot of times, don't want to do loads of allocations in onDraw

    public TickedProgressBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
         initPainters(context, attrs);

    public TickedProgressBarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initPainters(context, attrs);

    private void initPainters(Context context, @Nullable AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TickedProgressBarView, 0, 0);
            mInterval = a.getFloat(R.styleable.TickedProgressBarView_tickInterval, DEFAULT_INTERVAL);
        } else {
            mInterval = DEFAULT_INTERVAL;
        //5 on the line below is HALF how many Dp wide you want the circles - ie a 10 Dp circle results from this
        INDICATOR_RADIUS = 5 * getResources().getDisplayMetrics().density + 0.5f;
        mTickPaint = new Paint();
        mTickPaint.setColor(ContextCompat.getColor(getContext(), R.color.my_color));

    public void setTickInterval(float intervalPercentage) {
        mInterval = intervalPercentage;

    protected void onDraw(Canvas canvas) {
        if (mInterval > 0f) {
            final float midHeight = canvas.getHeight() / 2f;
            final int end = canvas.getWidth();
            final int intervalPx = (int) ((end / 100f) * mInterval);
            int nextInterval = intervalPx;
            while (nextInterval <= end) {
                canvas.drawCircle(nextInterval, midHeight, INDICATOR_RADIUS, mTickPaint);
                nextInterval += intervalPx;



<declare-styleable name="TickedProgressBarView">
    <attr name="tickInterval" format="float" />

The attr declaration allows you to use your view from xml

<!-- draw a circle every 10% along the bar -->