ProgressBar in an ActionBar, like GMail app with Refresh

痴心易碎 提交于 2019-12-20 08:42:09

问题


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


回答1:


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.




回答2:


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.




回答3:


Assuming that you already have your menu item setup, you'll need to start by creating two new layouts. One that contains the layout for the normal refresh button, and another that contains the progressbar.

Once you have them, call the following piece of code to switch between the two layouts. It'll be up to you to decide exactly when it needs to be called a second time in order to switch it back to the refresh icon.

private void doRefresh(Boolean refreshing, MenuItem menuItem)
{
    View refreshView;
    LayoutInflater inflater = (LayoutInflater) getActionBar().getThemedContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if(refreshing)
        refreshView = inflater.inflate(R.layout.actionbar_indeterminate_progress, null);
    else
        refreshView = inflater.inflate(R.layout.refresh_icon, null);

    menuItem.setActionView(refreshView);

}



回答4:


Use the following layout as the action view for the action bar menu item.

actionbar_refresh_progress.xml

<FrameLayout
    android:layout_height="wrap_content"
    android:layout_width="@dimen/abc_action_button_min_width"
    android:minWidth="@dimen/abc_action_button_min_width">
    <ProgressBar
        android:layout_width="32dp"
        android:layout_height="32dp"
         android:layout_gravity="center"
         style="?indeterminateProgressStyle" />
</FrameLayout>

Then

menuItem.setActionView(R.layout.actionbar_refresh_progress);

Works across Gingerbread and the rest like a charm. Note that I have used dimension from support action bar for compatibility. You can use @dimen/action_button_min_width instead for ICS and up.

Source: https://code.google.com/p/iosched/source/browse/android/res/layout/actionbar_indeterminate_progress.xml?r=f4fd7504d43b25a75cc23b58d6f844f3553b48c3



来源:https://stackoverflow.com/questions/8198253/progressbar-in-an-actionbar-like-gmail-app-with-refresh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!