Change icons in ActionBar dynamically

AndroidAndroid Actionbar

Android Problem Overview


I have an Activity which has an ActionBar but I need to change the icons on the ActionBar dynamically, I have a pause and a play button and I need to replace the play button with the pause button as the user click on it. I have searched and I found it:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if(DEBUG) Log.i("onCreateOptionsMenu()", "onCreateOptionsMenu() -> LogicAnalizerView");
	//menu.add("").setIcon(R.drawable.pause).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
    MenuInflater inflater = getMenuInflater();
	inflater.inflate(R.menu.actionbarlogic, menu);
    menu.removeItem(R.id.pauseLogic);
		
	return true;
}

So in this way I remove the Pause button and I can add it too, but it only happen when I start the Activity and the ActionBar is drawn. How can I force to redraw the ActionBar? Also, on this way the whole ActionBar is redrawn. Is that right? Is any way to redraw only the button/icon I want?

Thank you :)

Android Solutions


Solution 1 - Android

You'll have to save off a reference to the MenuItem after doing the inflation. So something like the following:

public boolean onCreateOptionsMenu( Menu menu ) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate( R.menu.actionbarlogic, menu );
    playMenu = menu.findItem(R.id.playMenu);
    updatePlayStatus();
    return menu;
}

public void updatePlayStatus() {
    if( playService.isConnected() ) {
        playService.isPlaying() ? playMenu.setIcon(R.drawable.pause) : playMenu.setIcon(R.drawable.play);
    }
}

Then you can refer to the playMenu anytime. So you can modify the item as say your player finishes playing and should go back to a play icon.

Solution 2 - Android

Instead of removing them, you could just hide the button you don't want displayed.

For example:

private boolean isPlaying;
MenuItem mPlayMenuItem;
MenuItem mPauseMenuItem;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu items for use in the action bar
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.actionbarlogic, menu);

    mPlayMenuItem = menu.findItem(R.id.action_play);
    mPauseMenuItem = menu.findItem(R.id.action_pause);

    return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    
    switch (item.getItemId()) {
        case R.id.action_play:
            isPlaying = true;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                this.invalidateOptionsMenu();
            }
            return true;
        case R.id.action_pause:
            isPlaying = false;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                this.invalidateOptionsMenu();
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}


 @Override
public boolean onPrepareOptionsMenu (Menu menu) {
    super.onPrepareOptionsMenu(menu);

    if (isPlaying) {
        mPlayMenuItem.setVisible(false); // hide play button
        mPauseMenuItem.setVisible(true); // show the pause button
    } else if (!isPlaying) {
        mPlayMenuItem.setVisible(true); // show play button
        mPauseMenuItem.setVisible(false); // hide the pause button
    }

    return true;
}

Just a note, this:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
     this.invalidateOptionsMenu();
}

is required to update the action bar. After 3.0 devices, the action bar does not automatically update itself. So, you have to manually tell it to call the "OnPrepareOptionsMenu(Menu)" so that it will refresh the items by calling the "Activity.invalidateOptionsMenu()".

Hope this helps!

Reference: http://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu(android.view.Menu)

http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#invalidateOptionsMenu(android.app.Activity)

Solution 3 - Android

private Menu mMenu;

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main_activity, menu);
	
	// Save the menu reference
    mMenu = menu;
    return super.onCreateOptionsMenu(menu);
}

// For example - Call when you need to change icon
private void setActionIcon(boolean showWithBadge)
{
    MenuItem item = mMenu.findItem(R.id.ITEM_ID);
    
    if(mMenu != null)
    {
        if(showWithBadge)
        {
            item.setIcon(R.drawable.IC_WITH_BADGE);           
        }
        else 
        {
            item.setIcon(R.drawable.IC_WITHOUT_BADGE);
        }
    }
}

Solution 4 - Android

If you want to get the first item from your menu, **

> use menu.getItem(0);

this Code woks perfectly :

 @Override
public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_menu, menu);
       MenuItem m =  menu.getItem(0);
       m.setIcon(R.drawable.your_icon_here);
    }


    return true;
}

Solution 5 - Android

Override the onPrepareOptionsMenu in your activity class and then you can add/ remove or visible/invisible menu items.

Solution 6 - Android

Use invalidateOptionsMenu() method.

private boolean isPlaying;

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.actionbarlogic, menu);
    if (isPlaying) menu.removeItem(R.id.play_button);
    else menu.removeItem(R.id.pause_button);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.play_button:
            // Do what the play button should do here
            isPlaying = true;
            break;

        case R.id.pause_button:
            // Do what the pause button should do here
            isPlaying = false;
            break;
    }
    invalidateOptionsMenu();
    return true;
}

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
QuestionAndresView Question on Stackoverflow
Solution 1 - AndroidchubbsondubsView Answer on Stackoverflow
Solution 2 - AndroidSandy D.View Answer on Stackoverflow
Solution 3 - AndroidDavidView Answer on Stackoverflow
Solution 4 - AndroidMallow66View Answer on Stackoverflow
Solution 5 - AndroidParinda RajapakshaView Answer on Stackoverflow
Solution 6 - AndroidMohit AtrayView Answer on Stackoverflow