18

I would like to add an indeterminate progress bar to the Honeycomb ActionBar, so that any time the user presses "Refresh", the refresh icon temporarily turns into an indeterminate progress bar, until the task completes. The Email app does this already, but I can't figure out how.

Any advice?

Melllvar
  • 2,056
  • 4
  • 24
  • 47
  • Related for refresh/refreshing : http://stackoverflow.com/questions/9731602/animated-icon-for-actionitem – rds Oct 30 '12 at 23:36

6 Answers6

19

To clarify Jon O's answer, the key is to set and unset an action view on the refresh action. This works in both ActionBarSherlock and native 4.x action bar. The following snippet will put the progress indeterminate view on top of the refresh icon, assuming the refresh menu item has ID 'refresh_option' and the replacement layout (which has a ProgressBar) is in layout 'progress_wheel':

 MenuItem item = abmenu.findItem(R.id.refresh_option);
 LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 View abprogress = inflater.inflate(R.layout.progress_wheel, null);
 item.setActionView(abprogress);

Unset the progress view, and the refresh icon will return to visibility:

 item.setActionView(null);

See a more detailed example on github.

larham1
  • 11,736
  • 5
  • 35
  • 26
  • The problem is: new ProgressBar is a bit wider than regular action item. Thus all neighboring items shift to the sides a bit whne it appears (and "jumb back" when it disappears). Any idea on how to solve this? – Alex Semeniuk Apr 22 '15 at 08:35
  • Anyone else seeing what I am seeing in AndroidX, where setActionView() (to either a View or a layout) just makes actionbar MenuItems disappear?? – RobP Nov 03 '21 at 14:59
5

To simplify larham1's answer: you don't even need to inflate new action view itself because MenuItem has the method which accepts id of action layout, so you can simply write:

item.setActionView(R.layout.progress_bar);
Community
  • 1
  • 1
aga
  • 27,954
  • 13
  • 86
  • 121
5

Hard to tell exactly how the Email app does it, but you may want to stay simple and just call setIcon with the id of a StateDrawable XML file, and then just change the state using a Timer.

Femi
  • 64,273
  • 8
  • 118
  • 148
  • 2
    Set icon is only possible for a tab Icon and not for the Actionbar itself. Is this working by accident also for ActionIcons or is this answer wrong? – Janusz Sep 13 '11 at 11:15
4

You can easily do it by:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_refresh: 
                item.setActionView(new ProgressBar(this));
                break;
        }
        return super.onOptionsItemSelected(item);
Heigo
  • 936
  • 8
  • 18
  • The problem is: new ProgressBar is a bit wider than regular action item. Thus all neighboring items shift to the sides a bit whne it appears (and "jumb back" when it disappears). Any ideas on how to solve this? – Alex Semeniuk Apr 22 '15 at 08:35
  • 1
    I created a layout file with the ``````. It avoids shifting of menu items. Remember to set the ```item.setActionView(R.layout.your_layout);``` – Devendra Vaja Jun 09 '17 at 23:16
4

It turns out that Google has posted an example of doing exactly this as a part of their broader ActionBarCompat compatibility project. Have a look.

Jon O
  • 6,532
  • 1
  • 46
  • 57
  • That example relies on a set layout with adjacent refresh icon and indeterminate progress, using show/hide. In the ActionBar, we don't have that layout nor access. Trying Femi's idea next... – larham1 Feb 10 '12 at 22:51
  • It does use show/hide on older devices, yes; however, if you look in the ActionBarHelperHoneycomb/ActionBarHelperICS classes, they do it the proper/updated way for ICS and Honeycomb too. It works on all devices (I know; I'm leveraging it in my own app for 2.1+, 3.x, and 4.x and it works on all of them, indeterminate progress bar included.) – Jon O Feb 14 '12 at 22:22
  • Link is now broken (Google decided to delete the URL? Sigh) – Adam May 03 '13 at 11:41
  • Unfortunately. But I think you can still get the code from the SDK examples for the android support libraries. Or google "actionbarcompat" and peek into one of the many github repositories that contain it in some form (I'm hesitant to link any one in particular). – Jon O May 03 '13 at 15:28
  • How can you replace the menu item button/icon with the indeterminate progressbar using the broadcast intents? ive tried this but keep failing. – Maxrunner Mar 05 '14 at 18:09
3

I'm using the code provided at the original issue here: https://github.com/JakeWharton/ActionBarSherlock/issues/425

Except for android:layout_width and android:layout_height (in the actionbar_indeterminate_progress.xml) I use 32dp; as this was the way it was done in ActionBarCompat: http://developer.android.com/resources/samples/ActionBarCompat/res/layout-v11/actionbar_indeterminate_progress.html

alexx
  • 603
  • 1
  • 6
  • 8