Standard Android SDK equipment provides developers with a wide range of components that can be used in application development. It is difficult to say how complete this set is and whether it meets all developer needs, however the platform itself is quite actively develops so we can expect that this set will be improved and expanded very often. And of course if something is missed in this set, you can always do it yourself :)
Among all this diversity you can find ProgressBar. This component is widely used to visualize the progress of a certain process or any other data. It needs almost everywhere. The component itself is quite simple and easy to use, but has a few nuances. For example it does not allows you to show some text on top of it. In case you need to do something like this:
there is no way to do it with default implementation. It seems to be okay, because you can always show the text somewhere on the bottom / top / left / right. But Android is a mobile platform, which means you have to fight for each pixel :). Well, let’s try to solve this problem.
There are at least 3 ways that comes to mind immediately:
- Built this component using existing ProgressBar and TextView
- Extend TextView class and add progress indicator as a background
- Extend ProgressBar and add text on top of it
The first option seems simple enough, but as the result you’ll have to work with three objects (TextView, ProgressBar, and container that combines them all in one) instead of one. Perhaps this is not something critical, but not awesome because final implementation seems a bit unwieldy for such a small task. Choosing between the second and third versions the last one seems most logical. After all, the main goal is to display an indicator whether the text is just a small supplement keeping in mind that you can actually live without it :). Although it is possible that the second option would be more acceptable for someone.
OK, let’s create a new TextProgressBar class extended from ProgressBar and add extra property to display text.
Our skeleton is ready now and we already can create an instance of this class and set up some text, text size and color. Now we will work directly with the problem. In order to display some text we will use onDraw() method and Paint class.
A few words about postInvalidate() method. Each time when we assign something to our variable (text, textColor or textSize) we must tell the system that our component has been modified and needs to be redrawn. To do this we use method postInvalidate().
TextProgressBar is ready now.
Layout.xml should look like this
At this point you may say “done”. Generally speaking you are right, but we still have one question. Why we cannot set text and other properties in xml directly like minHeight and layout_width? Let’s add this options
To do this we create another file /res/values/attrs.xml with the following structure:
- name – property name. This is what we will use in XML
- format – property type.You can read more here
Lets update our main.xml with this properties
Now we upgrade our TextProgressBar and add setAttrs method in which we read xml attributes
As the result our TextProgressBar class should look like this:
You should see the following picture now:
The last thing I’d like to cover here is branding. At the screenshot above you can see default ProgressBar look and feel. Lets do couple improvements to make it looks nice. To do this we will create another file /res/drawable/progressbar.xml with the following structure:
As you see we can set corner radius. Also, using gradient you can set background color to both parts. Let’s now apply this style using progressDrawable property
Thats it. If you have any ideas or suggestion – please let us know.