Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)?

like image 609
Darko Petkovski Avatar asked Apr 26 '16 10:04

Darko Petkovski


People also ask

In which mode a progress bar shows a cyclic animation without an indication of progress?

indeterminate: indeterminate attribute is used in Android to enable the indeterminate mode. In this mode a progress bar shows a cyclic animation without an indication of progress. This mode is used in application when we don't know the amount of work to be done. In this mode the actual working will not be shown.


1 Answers

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) {
        super(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));
        mTickPaint.setStyle(Paint.Style.FILL);
        mTickPaint.setStrokeCap(Paint.Cap.ROUND);
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(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;
            }
        }
    }

}

attrs.xml

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

The attr declaration allows you to use your view from xml

<!-- draw a circle every 10% along the bar -->
<com.my.packge.TickedProgressBarView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tickInterval="10.0"
/>
like image 77
Nick Cardoso Avatar answered Oct 02 '22 13:10

Nick Cardoso