在 Action Bar 中更改菜单项的视图

7

我正在尝试在我的应用程序中实现一个刷新按钮,以允许用户手动重新同步到Web服务器。代码可以正常工作,但我很难弄清楚操作视图(至少我认为我应该使用它们)。

我的菜单项在这里:

<item
    android:id="@+id/main_menu_refresh"
    android:enabled="true"
    android:icon="@drawable/refresh"
    android:orderInCategory="1"
    android:showAsAction="ifRoom"
    android:title="@string/refresh" 
    android:actionViewClass="android.widget.ProgressBar">
</item>

问题是它总是显示ProgressBar。我想知道它是否像搜索小部件一样工作(我在网上看到的唯一示例),并将collapseActionView标签添加到showAsAction中,这样可以防止它立即出现。但是,当我单击刷新按钮时,图标消失了(好的),但操作栏中的标题也消失了,并且ProgressBar出现在窗口左侧,原来是标题的位置。这也不是我想要的。作为最后一搏,我尝试向我的代码中添加此内容,并从XML中删除actionViewClass:
MenuItem refresh = (MenuItem)findViewById(R.id.main_menu_refresh);
Log.w("MyApp", "Have Menu");
ProgressBar pb = new ProgressBar(ReadingList.this);
refresh.setActionView(pb);

那也行不通,setActionView 给我返回了一个空指针错误。
我需要一个解决方案,可以从任何函数中调用(在开始时有自动同步周期,我希望 ProgressBar 在此期间显示),并且能够在之后将其恢复为静态图标。
我尝试阅读这个问题,但我很难理解答案的意思。我觉得我正在尝试做它所说的事情,但我想不是这样。非常感谢您的帮助。
编辑:对于 sastraxi 的建议。
public class IconSwitcher extends LinearLayout{



public IconSwitcher(Context context) {
    super(context);

    ProgressBar pb = new ProgressBar(context);
    ImageView iv = new ImageView(context);

    addView(iv);
    addView(pb);
}
}

这是我的课程进展。然而,当我尝试引用它时,请使用以下内容:
MenuItem refresh = (MenuItem)findViewById(R.id.main_menu_refresh);
IconSwitcher ic = (IconSwitcher) refresh.getActionView();

我遇到了空指针错误,当我创建IconSwitcher时。按钮的XML代码如下:
<item
    android:id="@+id/main_menu_refresh"
    android:enabled="true"
    android:icon="@drawable/refresh"
    android:orderInCategory="1"
    android:showAsAction="ifRoom"
    android:title="@string/refresh" 
    android:actionViewClass="IconSwitcher">
</item>

我只是在参考IconSwitcher视图方面遇到了困难。

编辑2:显然我完全无法引用菜单项。

MenuItem refresh = (MenuItem)findViewById(R.id.main_menu_refresh);
refresh.setVisible(false);

当我尝试设置可见性时,它给了我一个空指针。我的引用有什么问题吗?


我解决了。我找到了之前的SO问题。从那里,我发现了Google编写的代码,可以在这里进行操作here。此时基本上只需要复制和粘贴,就可以完美地工作了。 - The Holo Dev
这个问题不是出在 setActionView 上,而是在 (MenuItem)findViewById(R.id.main_menu_refresh) 这个地方。很明显,把 ActionItemView 转换为 MenuItem 是一个 ClassCastException。 - Namratha
3个回答

0

尝试使用:

<item
    android:id="@+id/main_menu_refresh"
    android:enabled="true"
    android:icon="@drawable/refresh"
    android:orderInCategory="1"
    android:title="@string/refresh"
    app:showAsAction="ifRoom"
    app:actionViewClass="android.widget.ProgressBar">
</item>

请注意这两行代码:
    app:showAsAction="ifRoom"
    app:actionViewClass="android.widget.ProgressBar"

0

你尝试过像这样获取菜单项吗?

MenuItem item = getToolbar().getMenu().findItem(Menu.FIRST);

0

不要将你的操作视图类设置为 ProgressBar,而是将其设置为自定义的 LinearLayout 类,如下所示:

class MyViewItem extends LinearLayout

在构造函数中使用addView添加一个ProgressBar和一个ImageView作为子元素,并根据代码需要将这些子元素的可见性设置为GONEVISIBLE

我有些难以理解。你能给我更多关于这个自定义类的细节吗?我在主贴中添加了更多内容,以展示我遇到的问题。 - The Holo Dev
你需要在XML中使用完全限定名称,例如com.mydomain.mypackage.IconSwitcher,而不是仅使用IconSwitcher。尝试这样做,看看是否开始工作。 - sastraxi
不行,我仍然有一个空指针错误。而且肯定是在 IconSwitcher ic = (IconSwitcher) refresh.getActionView(); 这一行。如果我将该行注释掉,就不会出现任何错误,但是我显然不会得到动态按钮,只有静态图标。我需要在清单文件中声明IconSwitcher吗? - The Holo Dev
你可以尝试使用 setActionView(new IconSwitcher(...)) 而不是在 XML 中设置 action view 类吗?我猜 Android 内部使用的是 MenuItemImpl,如果你这样设置它应该会返回非空值。此外,你也可以直接保留对它的引用... - sastraxi
嗯,我以为我一直在保留对它的引用,但事实证明,在我真正获取它之前,我在另一个线程中调用了该引用。我开始能够操作它了。此时,我认为我需要两个菜单项。一个是刷新图标。当按下它时,我会将进度条放在它的位置,而不是尝试更改图标本身。完成后,我会切换它们回来。 - The Holo Dev

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