Changing options menu/actionbar menu programatically for 3.0+

In short, here's my question:

Can option menus (shown in the actionbar) be modified programatically on android 3.0+?

I have a wizard-style activity in which I use a ViewFlipper to switch between views, or steps.

The steps are: 1 (nothing) -> 2 (menu) -> 3 (nothing).

Only the second screen (2) has a menu item, while the others don't, so I need the menu to be hidden/removed when the activity is shown, then visible/added after an action.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.mMenu = menu;

    getMenuInflater().inflate(R.menu.my_menu, menu);
    mMenu.getItem(0).setVisible(false);

    return super.onCreateOptionsMenu(menu);
}

Switch to the second screen ->

public void showNext(View v) {
    if (mVFlipper.getDisplayedChild() < (mVFlipper.getChildCount() - 1)) {
        mVFlipper.showNext();
        if (mVFlipper.getDisplayedChild() == 1) {
            setTitle("Second screen");
            mMenu.getItem(0).setVisible(true);
        }
    }
}

This works fine on 2.2, but fails miserably on 4.1. Starting off with a visible MenuItem, hiding it and displaying it later works. Starting off with an invisible menu item and showing it later doesn't work.

My main problem seems to be the fact that the MenuItem is invisible after onCreateOptionsMenu finishes executing. I could have the MenuItem stay visible for this method, but I have no other available callbacks in which to hide it.

Answers


There is a bug in Android's MenuItem setVisible that causes problems when turning items back to visible.

In your onCreateOptionsMenu(), add a check to see if the displayed page needs the Menu, if it does, add the MenuItem. Then, call invalidateOptionsMenu() whenever the page changes. That will rebuild the Menu.


I was also struggling with this issue, then I applied a small hack:

menu1.setEnabled(false);
menu1.setTitle("");

Then where you want to visible it again:

menu1.setEnabled(true);
menu1.setTitle("Okay"); //or you can set text according to your given updated values.

Problem fixed by having the MenuItem be visible after onCreateOptionsMenu finishes and then hiding it from a callback called after onCreateOptionsMenu:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.mMenu = menu;

    getMenuInflater().inflate(R.menu.my_menu, menu);        

    boolean dummyVal = super.onCreateOptionsMenu(menu);

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) {
        mMenu.getItem(0).setVisible(true);  
    } else {
        mMenu.getItem(0).setVisible(false);
    }

    return dummyVal;
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        if (mMenu != null) {
            mMenu.getItem(0).setVisible(false);
        }
    }
}

If anyone has this problem, I recommend trying toadzky's suggestion first: calling "invalidateOptionsMenu()".


Need Your Help

Change back css after .slideToggle()

javascript jquery html css

I have this issue: I want to set background color on hover element and slidetoggle a div inside it. But when item slide out i would like to set another background color to the element. Check the co...

Will the selenium IDE wait for timeout or execute the next command after 1000milliseconds(Setspeed)?

selenium timeout selenium-ide

If the setspeed is 1000milliseconds and default timeout is 30000milliseconds. Will the selenium IDE wait for timeout or execute the next command after 1000milliseconds?