How to update a menu item shown in the ActionBar?

AndroidMenuAndroid FragmentsAndroid Actionbar

Android Problem Overview


I have an Activity that has 2 fragments. Both are ListFragments and both contribute MenuItems to the Menu. I have one MenuItem that I've set the attribute android:showAsAction to have it show as a button on the ActionBar. Which works fine.

Now the MenuItem is state dependent. It's a Pause/Resume menu option for pausing and resuming a queue. My problem is I can't figure out how to set it's initial statue when the Fragment is created.

It's state is dependent on the whether the queue is paused or not. So I have an AsyncTask that gets the queue and sets a boolean (paused) based on the state of the queue. I'm calling onPrepareOptionsMenu to set the text for the Pause menu item based on the last known state of the queue and this works great if I leave the MenuItem in the actual menu. You tap the menu icon and onPrepareOptionsMenu is fired and the menu is updated before it's displayed.

The problem is, if I put that same MenuItem on the ActionBar (showAsAction), how can I force it to update without having to call onPrepareOptionsMenu? I need to be able to do this because on first launch of the app, I send a request to get the queue, but the task returns after the ActionBar is setup and displayed. I've created a handler in my fragment that gets called every time I get a queue update, but from there, how can I update the text for my MenuItem on the ActionBar? I can't seem to find a way to get the currently set Menu to manipulate it except for in onPrepareOptionMenu.

Rob W.

Android Solutions


Solution 1 - Android

Option #1: Try invalidateOptionsMenu(). I don't know if this will force an immediate redraw of the action bar or not.

Option #2: See if getActionView() returns anything for the affected MenuItem. It is possible that showAsAction simply automatically creates action views for you. If so, you can presumably enable/disable that View.

> I can't seem to find a way to get the currently set Menu to manipulate it except for in onPrepareOptionMenu.

You can hang onto the Menu object you were handed in onCreateOptionsMenu(). Quoting the docs:

> You can safely hold on to menu (and any items created from it), making modifications to it as desired, until the next time onCreateOptionsMenu() is called.

Solution 2 - Android

in my case: invalidateOptionsMenu just re-setted the text to the original one, but directly accessing the menu item and re-writing the desire text worked without problems:

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

due to the comment below, I was able to access the menu item via the following code:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.magazine_swipe_activity, menu);
    mnuTopMenuActionBar_ = menu;
    return true;
}

Solution 3 - Android

To refresh menu from Fragment simply call:

getActivity().invalidateOptionsMenu();

Solution 4 - Android

I have used this code:

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

And worked like a charm to me you can find OnPrepareOptionsMenu here

Solution 5 - Android

First please follow the two lines of codes to update the action bar items before that you should set a condition in oncreateOptionMenu(). For example:

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

Solution 6 - Android

For clarity, I thought that a direct example of grabbing onto a resource can be shown from the following that I think contributes to the response for this question with a quick direct example.

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

In this case you hold onto a MenuItem reference at the beginning and then change the state of it (for icon state changes for example) at a later given point in time.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbrockoliView Question on Stackoverflow
Solution 1 - AndroidCommonsWareView Answer on Stackoverflow
Solution 2 - AndroidcV2View Answer on Stackoverflow
Solution 3 - AndroidCoolMindView Answer on Stackoverflow
Solution 4 - AndroidASKView Answer on Stackoverflow
Solution 5 - AndroidsaranyaView Answer on Stackoverflow
Solution 6 - AndroidJay SnayderView Answer on Stackoverflow