Android 如何更新ActionBar中显示的菜单项?

Android 如何更新ActionBar中显示的菜单项?,android,menu,android-fragments,android-actionbar,Android,Menu,Android Fragments,Android Actionbar,我有一个活动有两个片段。两者都是ListFragments,都将菜单项添加到菜单中。我有一个菜单项,我设置了属性android:showAsAction,让它显示为操作栏上的按钮。这很好用 现在,菜单项依赖于状态。这是一个暂停/恢复菜单选项,用于暂停和恢复队列。我的问题是,当碎片被创建时,我不知道如何设置它的初始雕像 它的状态取决于队列是否暂停。因此,我有一个AsyncTask,它获取队列并根据队列的状态设置一个布尔值(暂停)。我正在调用PrepareOptions功能表,根据队列的最后一个已知

我有一个活动有两个片段。两者都是ListFragments,都将菜单项添加到菜单中。我有一个菜单项,我设置了属性android:showAsAction,让它显示为操作栏上的按钮。这很好用

现在,菜单项依赖于状态。这是一个暂停/恢复菜单选项,用于暂停和恢复队列。我的问题是,当碎片被创建时,我不知道如何设置它的初始雕像

它的状态取决于队列是否暂停。因此,我有一个AsyncTask,它获取队列并根据队列的状态设置一个布尔值(暂停)。我正在调用PrepareOptions功能表,根据队列的最后一个已知状态设置暂停菜单项的文本,如果我将菜单项保留在实际菜单中,这将非常有效。点击菜单图标,启动OnPrepareOptions功能表,并在显示前更新菜单

问题是,如果我将同一个菜单项放在操作栏(showAsAction)上,如何在不调用PrepareOptions功能表的情况下强制更新它?我需要能够做到这一点,因为在第一次启动应用程序时,我发送了获取队列的请求,但任务在ActionBar设置并显示后返回。我在我的片段中创建了一个处理程序,每次我得到队列更新时都会调用它,但是从那里开始,我如何在ActionBar上更新我的菜单项的文本?除了在onPrepareOptionMenu中,我似乎找不到一种方法来让当前设置的菜单操作它

Rob W.

选项1:试试看。我不知道这是否会迫使立即重画动作栏

选项2:查看
getActionView()
是否为受影响的
MenuItem
返回任何内容。
showAsAction
可能只是自动为您创建动作视图。如果是这样,您大概可以启用/禁用该
视图

除了在onPrepareOptionMenu中,我似乎找不到一种方法来让当前设置的菜单操作它

您可以挂起提交给您的
菜单对象
onCreateOptions菜单()
。引述:

您可以安全地保留菜单(以及从中创建的任何项目),根据需要对其进行修改,直到下次调用onCreateOptions菜单()


在我的例子中:
invalidateOptionsMenu
只是将文本重新设置为原始文本, 但是,直接访问菜单项并重新编写所需文本不会出现问题:

if (mnuTopMenuActionBar_ != null) {
    MenuItem mnuPageIndex = mnuTopMenuActionBar_
        .findItem(R.id.menu_magazin_pageOfPage_text);

    if (mnuPageIndex != null) {
        if (getScreenOrientation() == 1) {
            mnuPageIndex.setTitle((i + 1) + " von " + pages);
        }
        else {
            mnuPageIndex.setTitle(
                (i + 1) + " + " + (i + 2) + " " + " von " + pages);
        }
        // invalidateOptionsMenu();
    }
}
由于下面的评论,我能够通过以下代码访问菜单项:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.magazine_swipe_activity, menu);
    mnuTopMenuActionBar_ = menu;
    return true;
}
我使用了以下代码:

public boolean onPrepareOptionsMenu (Menu menu) {       
    MenuInflater inflater = getMenuInflater();
    TextView title  = (TextView) findViewById(R.id.title);
    menu.getItem(0).setTitle(
        getString(R.string.payFor) + " " + title.getText().toString());
    menu.getItem(1).setTitle(getString(R.string.payFor) + "...");
    return true;        
}

你可以在PrepareOptions功能表上找到我的魅力。为了清晰起见,我认为可以从下面的例子中看到一个抓住资源的直接例子,我认为这有助于快速直接回答这个问题

private MenuItem menuItem_;

@Override
public boolean onCreateOptionsMenu(Menu menuF) 
{
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_layout, menuF);
    menuItem_ = menuF.findItem(R.id.menu_item_identifier);
    return true;
}

在这种情况下,您在开始时保留菜单项引用,然后在稍后的给定时间点更改其状态(例如图标状态更改)。

首先请按照两行代码更新操作栏项 在此之前,您应该在oncreateOptionMenu()中设置一个条件。 例如:

Boolean mISQuizItemSelected = false;

/**
 * Called to inflate the action bar menus
 *
 * @param menu
 *      the menu
 *
 * @return true, if successful
 */

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu items for use in the action bar

    inflater.inflate(R.menu.menu_demo, menu);

    //condition to hide the menus
    if (mISQuizItemSelected) {
        for (int i = 0; i < menu.size(); i++) {
            menu.getItem(i).setVisible(false);
        }
    }

    return super.onCreateOptionsMenu(menu);
}

/**
 * Called when the item on the action bar being selected.
 *
 * @param item
 *      menuitem being selected
 *
 * @return true if the menuitem id being selected is matched
 * false if none of the menuitems id are matched
 */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getId() == R.id.action_quiz) {
        //to navigate based on the usertype either learner or leo
        mISQuizItemSelected = true;

        ActionBar actionBar = getActionBar();
        invalidateOptionMenu();
    }
}
Boolean mISQuizItemSelected=false;
/**
*调用以对操作栏菜单进行充气
*
*@param菜单
*菜单
*
*@return true,如果成功
*/
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单项充气,以便在操作栏中使用
充气机。充气(右菜单。菜单\u演示,菜单);
//条件隐藏菜单
如果(选择错误){
对于(int i=0;i
要从片段中刷新菜单,只需调用:

getActivity().invalidateOptionsMenu();
invalidateOptionsMenu()

在Kotlin 1.2中,只需调用:

getActivity().invalidateOptionsMenu();
invalidateOptionsMenu()

然后将再次调用创建选项菜单上的
函数。

尝试了选项1,这就成功了。因为我试图在一个单独线程的回调中更新UI,所以它抛出了一个异常,因为我实际上不在UI线程上。为了解决这个问题,我创建了一个处理程序,并在调用回调时向处理程序发送了一条刷新消息。但最终我使用getActivity().InvalidateOptions菜单()来刷新菜单。@brockoli:啊,太好了!考虑到Javadocs对该方法的措辞,我怀疑它是否会达到预期的效果,尽管这似乎是他们最初将其添加到API级别11的原因。很高兴听到它对你有用!我一直在想办法解决这个问题,我的头撞到了墙上,它就像一个符咒!如果您正在使用支持库,请使用
supportInvalidateOptionsMenu()
instead@TimKist,
supportInvalidateOptionsMenu()
现在已不推荐使用;您可以安全地使用
invalidateOptions功能表()
。您是如何通过
mnutopmenuationbar\uu
获得ActionBar视图的句柄的?操作栏初始化后,我将视图保存到成员变量中。。。如下所示:@Override public boolean onCreateOptions菜单(菜单菜单菜单){MenuInflater=getMenuInflater();inflater.inflate(R.Menu.magage\u swipe\u activity,Menu);mnutopmenuationbar\uu=Menu;return true;}这样做,您就可以有同步问题了,对吗?我是说。你不知道什么时候发生的