I would like to do the same thing than the GMail application on Honeycomb tablets. When you click on the Refresh button, the icon is replaced by a ProgressBar. How can I do this?
Thanks
Ok, I tried what Cailean suggested but it didn't work for me. Every time I want to revert indeterminate progress to the original button it becomes unclickable, I used this layout for the progress
(actionbar_refresh_progress.xml)
<?xml version="1.0" encoding="utf-8"?> <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="32dp" android:layout_height="32dp" android:layout_gravity="center"/>
and this one to revert to the button
(actionbar_refresh_button.xml)
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/ic_menu_refresh_holo_light" android:layout_height="wrap_content" android:layout_width="wrap_content"/>
my code was:
private void setRefreshing(boolean refreshing) { this.refreshing = refreshing; if(refreshMenuItem == null) return; View refreshView; LayoutInflater inflater = (LayoutInflater)getActionBar().getThemedContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); if(refreshing) refreshView = inflater.inflate(R.layout.actionbar_refresh_progress, null); else refreshView = inflater.inflate(R.layout.actionbar_refresh_button, null); refreshMenuItem.setActionView(refreshView); }
After browsing the source of the Google IO app, especially this file: http://code.google.com/p/iosched/source/browse/android/src/com/google/android/apps/iosched/ui/HomeActivity.java i found another easier way.
Now I need only the first layout with progress and the working method looks like this:
private void setRefreshing(boolean refreshing) { this.refreshing = refreshing; if(refreshMenuItem == null) return; if(refreshing) refreshMenuItem.setActionView(R.layout.actionbar_refresh_progress); else refreshMenuItem.setActionView(null); }
Menu item definition:
<item android:id="@+id/mail_refresh" android:title="Refresh" android:icon="@drawable/ic_menu_refresh_holo_light" android:showAsAction="always"/>
I hope someone finds this useful.
Gmail does this using an action view for its "refresh in progress" state. Invoking a refresh is done using the standard action button/onMenuItemSelected path.
When you enter your refreshing state, set the action view of the refresh MenuItem to a ProgressBar. (Create it programmatically, inflate it from a layout, use actionLayout in the menu xml as CommonsWare suggests, whatever you prefer.) When you exit your refreshing state, set the action view back to null while keeping a reference to it so you can set it back again the next time you refresh. You can hang onto a reference to the MenuItem after you inflate the menu and changes to it later will be reflected in the action bar.
This approach has some advantages over using a full-time action view and managing other details of the state change yourself. An action view completely replaces the generated action button for a menu item, effectively blocking the user from being able to send the usual onMenuItemSelected events for refresh while a refresh is already in progress. One less thing to handle and the action view can stay completely non-interactive.
You could probably do something clever with an ActionProvider in API 14+ to encapsulate the whole process a bit more but the above ends up being pretty simple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With