Basics of building a circular progress view

There are many libraries out there of fancy circular loading views based on percentages and whatnot, but they do not always cover all the things developers and/or organization want them to do. Honestly, I never looked at the source code for the circular loading libraries, and over the past week due to a project I’m working on, wondered how it was done without using a library. This post will explain the starting point for a custom circular view.

The problem can be solved drawing arcs on a canvas arcs, instead of circles.

In general, an arc is any smooth curve joining two points. The length of an arc is known as its arc length. In a graph, a graph arc is an ordered pair of adjacent vertices. In particular, an arc is any portion (other than the entire curve) of the circumference of a circle.

Lets take a look at what we want on paper before beginning.

From the bad drawing above, we can see that we need 2 arcs. One to represent the normal, un-filled circle, and another inside of it to represent the filled up percentage. Lets start with the main arc.

We create a custom class that extends View and draw the parent arc. The arc that represents the circular view without any percentages displayed.

The RectF is required in one of the Canvas#drawArc() overloaded methods.

RectF holds four float coordinates for a rectangle. The rectangle is represented by the coordinates of its 4 edges (left, top, right bottom). These fields can be accessed directly. Use width() and height() to retrieve the rectangle’s width and height. Note: most methods do not check to see that the coordinates are sorted correctly (i.e. left <= right and top <= bottom).

It is important that we realize that the style of the Paint object is set to Stroke. All Paint styles are straight forward, meaning that the center of the shape that the arc draws will not be filled up, only the borders will be shown.

By running this code alone, we will see a single arc drawn at the center of the screen.

Ok, so we know that an arc can pretty much draw pieces of a circle, in the example above we draw the circle, from 0 degrees (start point) to 360 (end point). We need to draw another arc on top of the existing arc with a different color (lets say green), to represent the percentage wanted. Normally, we think of percentages for anything going from 0% to 100%. So how can we do this when the arcs 100% is 360 degrees? With very simple math: fillPercentage = 360 (PERCENTAGE_WE_WANT / 100)

So if we wanted to draw a 25% fill to our existing arc, we would replace PERCENTAGE_WE_WANT with 25 to get the percentage for 360 degrees.

Thats pretty much it. The code to get started is extremely simple, but can be used to create complex circular loading views. I hope this helps.

Here is the full code for the CircularProgressView class. Full code with sample can be found HERE.