Animation / Drawable / Material Design / ProgressBar / VectorDrawable

Indeterminate – Part 1

Indeterminate ProgressBars are a useful tool for communicating to our users that an operation is in progress when we cannot predict how long it is likely to take. Previously on Styling Android we’ve covered how to create a backwardly compatible approximation of the material styled horizontal indeterminate ProgressBar but we haven’t looked at the circular form – in this series we’ll create an approximation of the material circular indeterminate ProgressBar which will be backwardly compatible to API 11 (Honeycomb).

This series is going to be slightly different to the normal structure on Styling Android. Initially we’re actually going to take a dive in to the Lollipop+ implementation of this control to understand precisely how it works – which is rather interesting. Then we’ll apply that knowledge and create a backwardly compatible version that is actually pretty close IMO.

Before we begin let’s just take a look at what we’re trying to achieve:

So it’s a section of a circle which sweeps round suddenly while the whole thing is rotating. Let’s look at how this is actually implemented by looking at the AOSP code at https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/res/res/drawable/progress_medium_material.xml:

It’s no great surprise that an AnimatedVectorDrawable is used here – this is for Lollipop+, after all and a holo drawable will be used when running on older devices. So this applies two different animations – one to achieve the sweep effect, and the other to perform the overall rotation. This is performed on res/drawable/vector_drawable_progress_bar_medium.xml:

I’m not going to do dive in to the pathData here, but this path essentially describes a circle. However nothing will actually be rendered because of the trimPath* values (actually because trimPathEnd="0" stop the path drawing at the beginning of the path).

It is worth noting the named of the path and group elements which tie in to the animators that get applied to them in the AnimatedVectorDrawable that we’ve already looked at. The rotation Animator gets applied to the group (and this is actually pretty standard stuff, so we won’t go in to any detail here – look at the AOSP source if you’re interested). But the Animators which apply the sweep animations are rather more interesting:

There are three Animators here which will run in parallel each one will alter one of the trimPath* attributes of the path element in our. For a recap on how we can achieve some interesting effects with trimPath take a look at .

It is the first two which control the start and end points on the circle and an arc will be rendered between these points. So by varying them at different rates over the duration of the Animator the desired “sweep” effect will be achieved. But the parameters for both are almost identical with the exception of the interpolator being applied.

The third animator is actually performing an offset of everything and its precise role in all of this will become clearer later on in the series when we actually come to roll our own implementation.

Regular readers of Styling Android will know that I love interpolators and these ones are particularly interesting. We’ll cover these in detail in the next article.

As this series is initially an exploration of AOSP code there is no accompanying source code. Yet. It will come later in the series, I promise!

© 2016, Mark Allison. All rights reserved.

CC BY-NC-SA 4.0 Indeterminate – Part 1 by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.

Leave a Reply

Your email address will not be published. Required fields are marked *