Android Framework has widgets that can make your application more intuitive and convenient with a graphic representation of some progress. These are ProgressBar and SeekBar, but their appearance may not be suited to your application's visual style.
In this topic, we will take a look at how you can customize ProgressBar and SeekBar to make them suitable for your application design.
ProgressBar
How can you customize ProgressBar? You should set android:progressDrawable. But let's create one first:
<?xml version="1.0" encoding="utf-8"?>
<!--our_progress_drawable.xml-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dp" />
<gradient
android:startColor="#B300BFFF"
android:centerColor="#00BFFF"
android:centerY="0.75"
android:endColor="#CE00BFFF"
android:angle="270"
/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dp" />
<gradient
android:startColor="#B30062FF"
android:centerColor="#0062FF"
android:centerY="0.75"
android:endColor="#CE0062FF"
android:angle="270"
/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dp" />
<gradient
android:startColor="#B30800FF"
android:centerColor="#0800FF"
android:centerY="0.75"
android:endColor="#CE0800FF"
android:angle="270"
/>
</shape>
</clip>
</item>
</layer-list>
Here we've defined <layer-list> with three items:
-
@android:id/background -
@android:id/secondaryProgress -
@android:id/progress,
which define background, secondaryProgress, and progress, respectively. In this example, we used shapes but items could be also Color or 9-patch. However, vector drawable won't work here. Now, let's apply our progressDrawable to ProgressBar:
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminateOnly="false"
android:maxHeight="20dp"
android:minHeight="20dp"
android:progress="25"
android:progressDrawable="@drawable/our_progress_drawable"
android:secondaryProgress="50" />
We restricted height with android:maxHeight and android:minHeight and set ProgressBar to the determinate mode with android:indeterminateOnly="false". Without the last attribute, ProgressBar would be in the indeterminate mode by default. Previously, the style we assigned set this attribute for us. And finally, we set our_progress_drawable to android:progressDrawable. Let's take a look at the result:
So, we've created our custom determinate ProgressBar, but what if we wanted to customize indeterminate ProgressBar? In such case we should create a drawable that will rotate:
<?xml version="1.0" encoding="utf-8"?>
<!--rotate_drawable.xml-->
<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="4"
android:shape="ring"
android:thicknessRatio="5.333"
android:useLevel="false">
<size
android:width="18dp"
android:height="18dp" />
<gradient
android:centerColor="#880800FF"
android:centerY="50%"
android:endColor="#ff0800FF"
android:startColor="#000800FF"
android:type="sweep"
/>
</shape>
</rotate>
android:useLevel tells us that this drawable could be drawn partially. In this case, we don't want this behavior, so we set it to false.
We defined the ring shape with gradient color, then put it inside <rotate>. Now we can assign it to a ProgressBar like this:
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/rotate_drawable"
android:indeterminateOnly="true" />
And here is what we get from the snippet above:
ProgressBar and its descendants don't work with vectors in determinate mode. Only with bitmaps and shapes.
SeekBar
SeekBar is an extension of ProgressBar, so that means they have mostly the same attributes. For example, we still have android:max, android:progress, android:secondaryProgress, and we can customize it with android:progressDrawable.
We also can define and set custom thumb drawable! Here's how we define our drawable:
<?xml version="1.0" encoding="utf-8"?>
<!-- thumb.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadiusRatio="4"
android:shape="ring"
android:thicknessRatio="5.333"
android:useLevel="false">
<size
android:width="18dp"
android:height="18dp" />
<solid android:color="#880800FF" />
</shape>
We again set android:useLevel, otherwise the drawable could be drawn partially or in this particular case won't be displayed at all.
Let's set it to SeekBar with the android:thumb attribute:
<SeekBar
android:id="@+id/seekBar"
android:progress="50"
android:thumb="@drawable/thumb"
android:secondaryProgress="70"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
And here is the result:
RatingBar customization is beyond the scope of the topic but you can read about it if you want on StackOverflow.
Conclusion
In this topic, you've learned how to use customized ProgressBar and SeekBar. Now you know how to:
-
Customize
ProgressBarwidget withandroid:progressDrawable -
Customize
ProgressBarin indeterminate mode withandroid:indeterminateDrawable -
Customize
SeekBar