ActionBar中的ProgressBar,例如带有Refresh的GMail应用程序

时间:2011-11-19 23:44:04

标签: android gmail progress-bar android-3.0-honeycomb tablet

我想和Honeycomb平板电脑上的GMail应用程序做同样的事情。 单击“刷新”按钮时,图标将替换为ProgressBar。 我怎么能这样做?

由于

4 个答案:

答案 0 :(得分:25)

Gmail使用操作视图为其“正在刷新”状态执行此操作。使用标准操作按钮/ onMenuItemSelected路径调用刷新。

当您进入刷新状态时,请将刷新MenuItem的操作视图设置为ProgressBar。 (以编程方式创建,从布局中膨胀,在CommonsWare建议的菜单xml中使用actionLayout,无论您喜欢什么。)当您退出刷新状态时,将操作视图设置回null,同时保持对它的引用,以便您可以设置下次刷新时它会再次返回。在菜单膨胀后,您可以挂起对MenuItem的引用,稍后对其进行的更改将反映在操作栏中。

这种方法比使用全时动作视图和自己管理状态变化的其他细节有一些优势。操作视图完全替换菜单项的生成的操作按钮,有效地阻止用户在刷新已经进行时发送通常的onMenuItemSelected事件以进行刷新。少处理一下,动作视图可以保持完全非交互。

您可以使用API​​ 14+中的ActionProvider做一些聪明的事情,以便将整个过程封装得更多,但上述结果非常简单。

答案 1 :(得分:25)

好的,我尝试了Cailean的建议,但它对我不起作用。每当我想将不确定的进度恢复到原始按钮时,它就变得无法点击,我将这个布局用于进度

(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"/>

这个还原到按钮

(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"/>

我的代码是:

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);
    }

浏览了Google IO应用的来源,特别是此文件:http://code.google.com/p/iosched/source/browse/android/src/com/google/android/apps/iosched/ui/HomeActivity.java我找到了另一种更简单的方法。

现在我只需要第一个带有进度的布局,工作方法如下所示:

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);
}

菜单项定义:

<item android:id="@+id/mail_refresh"
      android:title="Refresh"
      android:icon="@drawable/ic_menu_refresh_holo_light"
      android:showAsAction="always"/>

我希望有人觉得这很有用。

答案 2 :(得分:8)

假设您已经设置了菜单项,则需要先创建两个新布局。一个包含普通刷新按钮的布局,另一个包含进度条。

获得它们后,请调用以下代码以在两个布局之间切换。您需要确定何时需要再次调用它才能将其切换回刷新图标。

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

}

答案 3 :(得分:1)

使用以下布局作为操作栏菜单项的操作视图。

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>

然后

menuItem.setActionView(R.layout.actionbar_refresh_progress);

在姜饼上工作,其余的就像魅力一样。请注意,我使用了支持操作栏中的维度来实现兼容性。您可以使用@dimen/action_button_min_width代替ICS及以上。

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