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

时间:2011-04-23 23:07:12

标签: android menu android-fragments android-actionbar

我有一个包含2个片段的Activity。两者都是ListFragments,并且都将MenuItems贡献给菜单。我有一个MenuItem我设置了属性android:showAsAction让它显示为ActionBar上的一个按钮。哪个工作正常。

现在MenuItem依赖于状态。它是暂停/恢复菜单选项,用于暂停和恢复队列。我的问题是,当创建片段时,我无法弄清楚如何设置它的初始雕像。

它的状态取决于队列是否暂停。所以我有一个AsyncTask来获取队列并根据队列的状态设置一个布尔值(暂停)。我正在调用PrepareOptionsMenu来根据队列的最后已知状态设置Pause菜单项的文本,如果我将MenuItem保留在实际菜单中,这将很有用。您点击菜单图标并触发onPrepareOptionsMenu,菜单会在显示之前更新。

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

Rob W。

7 个答案:

答案 0 :(得分:169)

选项#1:尝试invalidateOptionsMenu()。我不知道这是否会迫使立即重新绘制操作栏。

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

  

我似乎无法找到一种方法来获取当前设置的Menu来操作它,除了inPrepareOptionMenu。

您可以挂在Menu上的onCreateOptionsMenu()对象上。引用docs

  

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

答案 1 :(得分:12)

在我的情况下: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;
}

答案 2 :(得分:7)

要从Fragment刷新菜单,只需致电:

getActivity().invalidateOptionsMenu();

答案 3 :(得分:3)

我使用过这段代码:

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

对我来说就像魅力一样,你可以找到OnPrepareOptionsMenu here

答案 4 :(得分:2)

首先请按照两行代码更新操作栏项 在此之前,你应该在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();
    }
}

答案 5 :(得分:1)

为了清楚起见,我认为抓住资源的直接示例可以通过以下方式显示,我认为通过快速直接的示例有助于对此问题的响应。

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

在这种情况下,您在开头持有一个MenuItem引用,然后在稍后的给定时间点更改它的状态(例如,对于图标状态更改)。

答案 6 :(得分:-1)

Kotlin 1.2 中,只需致电:

invalidateOptionsMenu()

onCreateOptionsMenu函数将再次被调用。