Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ProgressBar in an ActionBar, like GMail app with Refresh

Tags:

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

like image 498
g123k Avatar asked Nov 19 '11 23:11

g123k


2 Answers

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.

like image 105
Ivan G. Avatar answered Oct 21 '22 10:10

Ivan G.


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.

like image 32
adamp Avatar answered Oct 21 '22 10:10

adamp