Indeterminate ProgressBar with custom image
Updated in AndroidTHe most common way to inform user that your app is doing something in the background is to show a ProgressBar to the user.
There are two types of ProgressBars available. The progress bar can either show distinct value like 34/76 or it can be indeterminate. In this tutorial we customize the indeterminate ProgressBar.
In the most simplest case indeterminate ProgressBar is written like this:
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
But if you want to show a custom drawable instead of the default one, you can use the indeterminateDrawable attribute:
<ProgressBar
...
android:indeterminateDrawable="@drawable/indeterminate_progress"
... />
You can use any drawable as the indeterminate drawable, but in order to make it look like something is happening, it makes sense to animate it. I personally prefer using xml drawables here.
For example very simple rotating indeterminate progress image can be achieved with this:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360">
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="10"
android:useLevel="false">
<gradient
android:angle="0"
android:endColor="#008577"
android:startColor="#00000000"
android:type="sweep"
android:useLevel="false" />
</shape>
</rotate>
Since drawable xml supports layer lists, you can combine two or more shapes or drawable instances to create complex image:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="5dp"
android:drawable="@android:drawable/ic_delete"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
<item>
<rotate
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360">
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="10"
android:useLevel="false">
<gradient
android:angle="0"
android:endColor="@color/colorPrimary"
android:startColor="@android:color/transparent"
android:type="sweep"
android:useLevel="false" />
</shape>
</rotate>
</item>
</layer-list>
If you want to change the rotation speed, there’s two things you can do. You can either change the amount of degrees the rotation makes or you can set the animation time.
To change the rotation just change the degrees:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
...
android:toDegrees="1080">
...
</rotate>
Remember to use multiples of 360 to make sure the rotation isn’t jumpy. The time it takes for the rotation to happen is listed below:
Degrees | Rotation time |
---|---|
360 | 4s |
720 | 2s |
1080 | 1.33s |
1440 | 1s |
Or you can set the exact time in the layout xml with indeterminateDuration:
<ProgressBar
...
android:indeterminateDuration="1500"
... />
indeterminateDuration takes milliseconds as the parameter, so in the above ProgressBar one full rotation takes 1.5 seconds.