indeterminateProgressBar in ActionBar styling - padding issue

I found a working solution how to set indeterminate progress bar with proper size and padding. My solution doesn't use workaround with setActionView(). It is solution for built-in progress bar functionality, supported by native action bar (ActionBarSherlock). Progress bar is enabled/disabled via setProgressBarIndeterminateVisibility(boolean) method. I tested it on Android 2, 3, 4 and ldpi, mdpi, xhdpi.

Result

AndroidManifest.xml:

<application
    ...
    android:theme="@style/Theme.Example">

/res/values/styles.xml:

<resources xmlns:android="http://schemas.android.com/apk/res/android">
    ...

    <style name="Theme.Example" parent="Theme.Sherlock">
        <item name="actionBarStyle">@style/Example.ActionBar</item>
        <item name="android:actionBarStyle">@style/Example.ActionBar</item>
    </style>

    <style name="Example.ActionBar" parent="Widget.Sherlock.ActionBar">
        <item name="indeterminateProgressStyle">@style/Example.ActionBar.IndeterminateProgressBar</item>
        <item name="android:indeterminateProgressStyle">@style/Example.ActionBar.IndeterminateProgressBar</item>
    </style>

    <style name="Example.ActionBar.IndeterminateProgressBar" parent="@android:style/Widget.ProgressBar.Large.Inverse">
        <item name="android:indeterminateDrawable">@drawable/layer_list_ab_indeterminate_progress_bar</item>
        <item name="android:minWidth">@dimen/ab_indeterminate_progress_bar_size</item>
        <item name="android:maxWidth">@dimen/ab_indeterminate_progress_bar_size</item>
        <item name="android:minHeight">@dimen/ab_indeterminate_progress_bar_size</item>
        <item name="android:maxHeight">@dimen/ab_indeterminate_progress_bar_size</item>
    </style>
</resources>

/res/drawable/layer_list_ab_indeterminate_progress_bar.xml:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <!--
        /res/drawable-mdpi/ab_indeterminate_progress_bar asset is taken from
        /sdk/platforms/android-18/data/res/mdpi/spinner_white_48.png
        and its content (optical square) is resized to ~0.6 (must be even number)

        /res/drawable-mdpi-v14/ab_indeterminate_progress_bar asset is taken from
        /sdk/platforms/android-18/data/res/mdpi/spinner_48_outer_holo.png
        and its content (optical square) is resized to 0.75
        -->
        <rotate
            android:drawable="@drawable/ab_indeterminate_progress_bar"
            android:interpolator="@android:anim/linear_interpolator"
            android:pivotX="50%"
            android:pivotY="50%"
            android:fromDegrees="0"
            android:toDegrees="360" />
    </item>
</layer-list>

/res/values/dimens.xml:

<dimen name="ab_indeterminate_progress_bar_size">48dp</dimen>

Finally I created progress bar assets. I used these two assets from Android SDK:

  • /sdk/platforms/android-18/data/res/mdpi/spinner_white_48.png for Honeycomb and older
  • /sdk/platforms/android-18/data/res/mdpi/spinner_48_outer_holo.png for ICS and newer

To get proper size and padding, we need to resize the assets. I resized spinner_white_48.png to ~0.6. For mdpi, it was 28px. It must be even number to be centrally symmetric. I resized only the content, not the whole icon. So icon in mdpi has still 48px, but its content (optical square) is smaller (28px). You can easily resize the content this way: first change "image size" to 28px X 28px, then change "canvas size" back to 48px X 48px. I resized spinner_48_outer_holo.png to 0.75. You can download the assets below.

Why do I use different assets for Honeycomb- and ICS+? Because if I'm using only Holo assets, the animation is little bit snatchy on some devices with Honeycomb-.

Tip: you can add another item with some animation to layer_list_ab_indeterminate_progress_bar.xml. For example standard Holo progress bar uses 2 animations with opposite direction and different degrees range. See progress_medium_holo.xml in SDK.

/res/drawable-mdpi/ab_indeterminate_progress_bar.png:

enter image description here

/res/drawable-mdpi-v14/ab_indeterminate_progress_bar.png (hardly visible on this page):

enter image description here

/res/drawable-hdpi/ab_indeterminate_progress_bar.png:

enter image description here

/res/drawable-hdpi-v14/ab_indeterminate_progress_bar.png (hardly visible on this page):

enter image description here

/res/drawable-xhdpi/ab_indeterminate_progress_bar.png:

enter image description here

/res/drawable-xhdpi-v14/ab_indeterminate_progress_bar.png (hardly visible on this page):

enter image description here


I meet this today and find a solution for Android 3/4+

ProgressBar mProgressBarInActionBar = null;
Resources res = Resources.getSystem();
int id = res.getIdentifier("progress_circular", "id", "android");
View internal = findViewById(id);
if(internal != null && internal instanceof ProgressBar){
    mProgressBarInActionBar = (ProgressBar)internal;
}
mProgressBarInActionBar.setPadding(0, 0, right, 0);

Set a suitable right :)


I don't know the exact answer but these settings worked for me..

This is my refresh_spinner.xml

    <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar android:layout_width="32dp"
 android:layout_height="32dp"
 android:layout_gravity="center"
 android:layout_marginRight="12dp"
 android:layout_marginLeft="12dp"
 style="?indeterminateProgressStyle" />
    </FrameLayout>

And this in the corresponding style xml

<style name="Widget.MyTheme.ActionBar" parent="Widget.Sherlock.ActionBar">
    <item name="indeterminateProgressStyle">?android:attr/progressBarStyleSmallInverse</item>
</style>

These settings worked for me. Please let me know if you have any doubts.

Regards Parvaz Bhaskar

EDIT2 : since I was trying different methods I ended up using ?android:attr/progressBarStyleSmallInverse as the only property in my style.xml which i later refrenced it from my spinner xml under style as style="?indeterminateProgressStyle"

EDIT: keep a reference of your menuItem and whenever you want to show a refresh progressbar use setActionView(R.layout.your_layout), and change it to null when the need is over. onCreateOptionsMenu would be a good place to grab the menuItem at start.