13

I want to put an indeterminate progress bar inside my ActionBar (using ActionBarSherlock). Everything works, but I want it to be the small progress bar. I use following style:

<style name="IndeterminateProgress" parent="@android:style/Widget.ProgressBar.Small"> <item name="android:progressBarPadding">32dp</item> <item name="progressBarPadding">32dp</item> <item name="android:itemPadding">32dp</item> <item name="itemPadding">32dp</item> </style> <style name="Widget.Styled.ActionBar.Tiles" parent="Widget.Sherlock.Light.ActionBar"> <item name="android:indeterminateProgressStyle">@style/IndeterminateProgress</item> <item name="android:progressBarPadding">32dp</item> <item name="progressBarPadding">32dp</item> <item name="android:itemPadding">32dp</item> <item name="itemPadding">32dp</item> </style> 

The problem is that I cannot set the padding on the progress bar. As you can see above, I've tried every possible combination of itemPadding and progressBarPadding, etc.

The result is always the same: enter image description here

Any ideas?

4 Answers 4

10

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

Sign up to request clarification or add additional context in comments.

1 Comment

Is there really no way to do this without making custom drawables and resizing assets? The desired effect can almost be obtained by setting minWidth, minHeight, maxWidth, maxHeight in the style as you mentioned, but the ProgressBar appears at the very corner (without the 3-dot overflow menu icon it looks horrible). Setting padding, layout_margin in the style has no affect. Why! why!!??
1

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.

3 Comments

Thanks but it didn't work. To be honest I don't know how it is supposed to work, since you don't reference the file refresh_spinner.xml anywhere in your style. Are you sure you mean a ProgressBar inside an ActionBar
Sorry I forgot to mention. I replace my menuItem when clicked with menuItem.setActionView(R.layout.refresh_spinner), and to change it back to normal I use menuItem.setActionView(null) to remove and retain the orignal icon
I was aware of the solution with action view. Was looking for the solution with the progressbar functionality which is built in the actionbar implementation - setProgressBarIndeterminateVisibility(true) Thanks anyway :)
1

I had the same problem and I found an easy answer:

<style name="ActionBarProgressBar.MyStyle" parent="@android:style/Widget.Holo.ProgressBar.Large"> <item name="android:minWidth">56dp</item> <item name="android:maxWidth">56dp</item> <item name="android:minHeight">35dp</item> <item name="android:maxHeight">35dp</item> </style> 

The Width is the standard Actionbar item width. If you change the minHeight and maxHeight, then the image will scale both ways.

And here is the Actionbar styling where you set the appearance of the Indeterminate Progress:

<style name="action_bar_theme" parent="@android:style/Widget.Holo.ActionBar"> <item name="android:indeterminateProgressStyle">@style/ActionBarProgressBar.MyStyle</item> </style> 

And the definition in the Theme you are using (don't forget to use it in your manifest):

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:actionBarStyle">@style/action_bar_theme</item> </style> 

Comments

0

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 :)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.