Estimated reading time: 3 minutes
Posted on February 23, 2012

Android & ProgressBar with Text

The standard Android SDK equipment provides developers with a wide range of components that can be used in application development. It is hard to say if this kit is ultimate and meets all developer needs, however, the platform itself is being continuously elaborated so we can expect the set to regularly get improvements and boast expanded functionality. At worst, you can always add something yourself if it’s missing :)

Among the whole component diversity you can find a ProgressBar. It is widely used to visualize the progress of a certain operation like downloading content or sending a message. The component itself is quite simple and easy to use but there are a few peculiarities. For example, you’re not allowed to show text in it. In case you need to do something like this:

there is no way of accomplishing it via default implementation. It seems to be no big deal because you can always have your text displayed somewhere at the bottom/top or on the left/right. But Android is a mobile platform which means you have to fight for each pixel :) So let’s try to crack this problem.

There are at least 3 solutions that come to mind immediately:

  • Building a component using the existing ProgressBar and a TextView
  • Extending the TextView class and adding a progress indicator as a background
  • Extending the ProgressBar and adding text to it

The first option seems simple enough, but as a result you’ll have to work with three objects (TextView, ProgressBar, and a container combining them all in one) instead of one. Perhaps, it is not a critical point but that’s not perfectly fine as the process of final implementation gets a bit bulky for such a small task. If choosing between the second and the third versions, I’d vote for the latter as the most logical. After all, the main goal is to display a progress indicator where text is just a small add-on you can actually do without :) Nevertheless, it is possible that the second option would be more acceptable for someone.

OK, let’s create a new TextProgressBar class extended from the ProgressBar and add extra property to display text.

Our skeleton is ready now and we can create an instance of this class and add some text, set its size and color. Now we will handle the problem directly. In order to show the text we will use an onDraw() method and a Paint class.

A few words about a postInvalidate() method. Each time we assign anything to our variable (text, textColor or textSize), we must tell the system that our component has been modified and should be redrawn. To do this, we use the method postInvalidate().

The TextProgressBar is ready now.

Layout.xml should look like this:

At this point you may say “done”. In general, you can finish here, but we still have one question. Why cannot we set text and other properties like minHeight and layout_width directly in xml ? Let’s add these options.

To do this, we create another file /res/values/attrs.xml with the following structure:

  • name – the property name. This is what we will use in XML;
  • format – the property type. You can read more here.

Lets update our main.xml with these properties.

Now we upgrade our TextProgressBar and add a setAttrs method in which we read xml attributes.

As a 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. On the screenshot above you can see a default ProgressBar appearance. Let’s add a couple of improvements to make it look nicer. To do this, we will create another file /res/drawable/progressbar.xml with the following structure:

As you see, we can set a corner radius. With the gradient, you can also set a background color to the both parts. Let’s now apply this style using the progressDrawable property.

And this is it! If you have any other related ideas or suggestions, please let us know. We’d be glad to hear from you!