【发布时间】:2012-01-02 03:38:18
【问题描述】:
我想做与 Honeycomb 平板电脑上的 GMail 应用程序相同的事情。 当您单击 Refresh 按钮时,图标将替换为 ProgressBar。 我该怎么做?
谢谢
【问题讨论】:
标签: android gmail progress-bar android-3.0-honeycomb tablet
我想做与 Honeycomb 平板电脑上的 GMail 应用程序相同的事情。 当您单击 Refresh 按钮时,图标将替换为 ProgressBar。 我该怎么做?
谢谢
【问题讨论】:
标签: android gmail progress-bar android-3.0-honeycomb tablet
使用以下布局作为操作栏菜单项的操作视图。
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 及更高版本。
【讨论】:
好的,我尝试了 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"/>
我希望有人觉得这很有用。
【讨论】:
假设您已经设置了菜单项,您需要从创建两个新布局开始。一个包含正常刷新按钮的布局,另一个包含进度条。
获得它们后,调用以下代码在两种布局之间切换。由您决定何时需要再次调用它以将其切换回刷新图标。
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);
}
【讨论】:
Gmail 使用“正在刷新”状态的操作视图来执行此操作。调用刷新是使用标准操作按钮/onMenuItemSelected 路径完成的。
当你进入你的刷新状态时,将刷新 MenuItem 的动作视图设置为一个 ProgressBar。 (以编程方式创建它,从布局中填充它,按照 CommonsWare 的建议在菜单 xml 中使用 actionLayout,无论您喜欢什么。)当您退出刷新状态时,将操作视图设置回 null,同时保留对它的引用,以便您可以设置下次刷新时它会再次返回。膨胀菜单后,您可以挂起对 MenuItem 的引用,稍后对其所做的更改将反映在操作栏中。
与使用全时操作视图和自行管理状态更改的其他细节相比,这种方法具有一些优势。操作视图完全替换了为菜单项生成的操作按钮,有效地阻止了用户在刷新正在进行时发送通常的 onMenuItemSelected 事件进行刷新。少了一件需要处理的事情,动作视图可以完全保持非交互性。
您可能可以使用 API 14+ 中的 ActionProvider 做一些巧妙的事情,以进一步封装整个过程,但以上内容最终变得非常简单。
【讨论】: