在操作栏中添加进度条,就像GMail应用程序中的刷新功能。

23

我希望在Honeycomb平板电脑上做与GMail应用程序相同的事情。 当您点击刷新按钮时,图标会被进度条替换。 我该怎么做呢?

谢谢

4个回答

25

Gmail通过为“刷新中”状态使用动作视图来实现此操作。使用标准的动作按钮/onMenuItemSelected路径进行刷新调用。

当您进入刷新状态时,将刷新 MenuItem 的操作视图设置为 ProgressBar。(根据您的喜好,可以通过编程方式创建它、从布局中膨胀出它、在菜单 xml 中使用 actionLayout,就像 CommonsWare 建议的那样。)当您退出刷新状态时,将动作视图设回 null,同时保留对其的引用,以便下次刷新时可以重新设置。您可以在膨胀菜单后保留对 MenuItem 的引用,稍后对其进行更改会反映在操作栏中。

相较于使用全时动作视图并自己管理状态变化的其他细节,这种方法具有一些优点。动作视图完全替换了菜单项的生成动作按钮,有效阻止用户在刷新已经在进行时发送通常的 onMenuItemSelected 事件。少了一件事要处理,而且动作视图可以完全不可交互。

您可能可以在 API 14+ 中使用 ActionProvider 来聪明地封装整个过程,但上述方法很简单。


我已经尝试过这个方法,除了在Android 4.0.3上的屏幕方向改变时会崩溃之外,其他都可以正常工作。有没有什么解决方法? - David Stocking
Buttink,你有异常堆栈跟踪吗?在JellyBean上看起来还不错。 - Ivan G.

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

我希望这对某些人有所帮助。


7
actionbar_refresh_progress的XML代码无法像刷新图标一样正确居中进度条。不过,按照链接转到Google IO应用程序并直接提取他们的actionbar_indeterminate_progress.xml文件,它能正常工作!https://code.google.com/p/iosched/source/browse/android/res/layout/actionbar_indeterminate_progress.xml - jcxavier

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

}

好的。你能展示一下你的refresh_icon.xml布局吗?每次我膨胀ImageView后,在调用doRefresh(false, ...)之后,按钮就会变得无法点击。 - Ivan G.
我已经按照这种方式做了,几乎一切都正常工作。问题是我的ProgressDialog没有动画效果。它会变得可见,然后不可见,但完全没有动画效果。我不明白为什么。 - Duqe

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

跨越Gingerbread和其他版本都能完美运行。请注意,我已经使用了支持操作栏的尺寸以实现兼容性。对于ICS及以上版本,您可以使用@dimen/action_button_min_width代替。
来源:https://code.google.com/p/iosched/source/browse/android/res/layout/actionbar_indeterminate_progress.xml?r=f4fd7504d43b25a75cc23b58d6f844f3553b48c3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接