9

In my activity's onCreateOptionsMenu method, I am simply inflating my menu layout file and attaching it.

I want to show/hide some menu items based on a value a of a global variable, I do this in the onPrepareOptionsMenu method. I've read that this is the correct place to do it.

My onPrepareOptionsMenu method doesn't always fire. I don't know why but it doesn't always fire when I press the "Menu" button on my phone. Maybe it has some thing to do with it's internal state.

It seems to fire when the Acitvity is being created. Pressing the "Menu" button for the first time, doesn't cause it to fire but if I press the menu button a second time, it works just fine.

Is there a way I could force the onPrepareOptionsMenu to fire.

Thanks


Smok suggested using the invalidateOptionsMenu method to invalidate the menu items but this causes the onCreateOptionsMenu method to fire too. Here's my method:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    System.out.println("onCreate");

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.search, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconified(false);
    searchView.requestFocusFromTouch();

    return true;

}

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    System.out.println("prepared");

    if (this.objAdapter == null) {
        menu.findItem(R.id.sort).setVisible(false);
        menu.findItem(R.id.filter).setVisible(false);
        menu.findItem(R.id.group).setVisible(false);
    } else {
        menu.findItem(R.id.sort).setVisible(true);
        menu.findItem(R.id.filter).setVisible(true);
        menu.findItem(R.id.group).setVisible(true);

    }

    return true;
}

As you can see from my onCreateOptionsMenu method, invoking it again will cause the focus to be lost to the SearchView.

Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
  • 1
    Are you using ActionBar? Check [this answer](http://stackoverflow.com/questions/7659354/when-and-how-often-onprepareoptionsmenu-method-is-called-for-actionbar) – smok Sep 13 '12 at 12:10
  • Hi Smok, I've tried that already and that worked but it caused additional complications. It also causes my `onCreateOptionMenu` method to get triggered for some reason. I'm am instantiating my `SearchView` in this method and setting the focus to the `SearchView` so that the user can begin searching. If the `invalidateOptionsMenu` is needed to cause the `onPrepareOptionsMenu` to fire and the `onCreateOptionsMenu` gets fired too, the focus goes back to the `SearchView`. Seems to be a Catch-22 situation. Any more suggestions? – Mridang Agarwalla Sep 13 '12 at 12:23

3 Answers3

24

As Smok pointed out: by calling invalidateOptionsMenu().

Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
3

I had the same issue and I fixed with supportInvalidateOptionsMenu() method (because I use support activity) but with a workaround.

I have a flag variable that I check in the onCreateOptionsMenu(Menu menu) method in this way:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (!IS_MENU_FIXED) {
        // Create menu only the first time the activity is loaded
        super.onCreateOptionsMenu(menu);
        getSupportMenuInflater().inflate(R.menu.main, menu);
        // Create menu items, etc...
    }
    return true;
}

And this is the way I call supportInvalidateOptionsMenu() when is required:

if (!IS_MENU_FIXED) {
    supportInvalidateOptionsMenu();
    IS_MENU_FIXED = Boolean.TRUE;
}

This is the Official documentation about this topic.

Regards, Gabriel.

Gabriel Volpe
  • 101
  • 1
  • 8
0

I use this code in a navigationDrawer Activity, which has two fragments (FullCoinsFragment & NewsFragment) nested:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.navigation, menu);

    MenuItem item = menu.findItem(R.id.action_search); //i will remove it later
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
    searchView.setOnQueryTextListener(this);

    return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    FullCoinsFragment test = (FullCoinsFragment)getSupportFragmentManager().findFragmentByTag(FRAGMENT_COINS);
    if (test != null && test.isVisible()) return true; // i don't want to show this menu search in NewsFragment
    menu.removeItem(R.id.action_search); //i'm removing the search option
    return true;
}

In my NewsFragment's onCreate() i have this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_news, container, false);

    //views initialization

    getActivity().invalidateOptionsMenu(); //i'm forcing the call to onCreateOptionsMenu() and onPrepareOptionsMenu

    return view;
}
Saul_programa
  • 341
  • 1
  • 4
  • 13