【问题标题】:ProgressBar in an ActionBar, like GMail app with RefreshActionBar 中的 ProgressBar,例如带有 Refresh 的 GMail 应用程序
【发布时间】:2012-01-02 03:38:18
【问题描述】:

我想做与 Honeycomb 平板电脑上的 GMail 应用程序相同的事情。 当您单击 Refresh 按钮时,图标将替换为 ProgressBar。 我该怎么做?

谢谢

【问题讨论】:

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


    【解决方案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 和其他产品,就像魅力一样。请注意,为了兼容性,我使用了支持操作栏中的维度。您可以使用 @dimen/action_button_min_width 代替 ICS 及更高版本。

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

    【讨论】:

      【解决方案2】:

      好的,我尝试了 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"/>
      

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

      【讨论】:

      【解决方案3】:

      假设您已经设置了菜单项,您需要从创建两个新布局开始。一个包含正常刷新按钮的布局,另一个包含进度条。

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

      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, ...); 后按钮变得不可点击;
      • 我已经这样做了,几乎一切正常。问题是我的进度对话框没有动画。变得可见,然后不可见,但根本没有动画。不明白为什么。
      【解决方案4】:

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

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

      与使用全时操作视图和自行管理状态更改的其他细节相比,这种方法具有一些优势。操作视图完全替换了为菜单项生成的操作按钮,有效地阻止了用户在刷新正在进行时发送通常的 onMenuItemSelected 事件进行刷新。少了一件需要处理的事情,动作视图可以完全保持非交互性。

      您可能可以使用 API 14+ 中的 ActionProvider 做一些巧妙的事情,以进一步封装整个过程,但以上内容最终变得非常简单。

      【讨论】:

      • 我已经尝试过了,除了在 android 4.0.3 中它会在屏幕方向更改时崩溃。有没有办法解决这个问题?
      • Buttink 你有异常堆栈跟踪吗? JellyBean 上看起来不错。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-09
      • 2012-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多