10

For some reason, my onCreateOptionsMenu and onPrepareOptionsMenu run twice (checked with a log input on the start of both methods). This happens for multiple fragments that I have, including some that are very basic (just inflating the menu, nothing else).

This is one of the onCreateOptionsMenus that has this issue:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.actionbuttons_add_removeall, menu);
    optionsMenu = menu;
}

What could cause these methods to be called multiple times (mostly twice)?


Update

I found out this is being caused (in some way) by the RecyclerView I'm using. All the views that are having this issue use a RV, the view I mentioned before that didn't have this issue, indeed doesn't. With this new info, which part of the RV could possibly be posing this issue?

Update2

I found out that I call .invalidateOptionsMenu() in the getItemCount() method in the Adapter. I thought that this would call onPrepareOptionsMenu(), but reading the docs, it seems like it calls onCreateOptionsMenu(). I'm probably getting onCreate..() and onPrepare..() reversed here, gonna check that out now.

Update3

I have just realized that I invalidate the options menu in my RecyclerViewAdapter, in the getItemCount() method, which obviously runs when the fragment is first created.

@Override
public int getItemCount() {
    int tableSize = getTableSizeMethod();

    if (tableSize < 1) {
        if (!AppManagerFragment.hideDeleteAllButton) {
            AppManagerFragment.hideDeleteAllButton = true;
            ((Activity) context).invalidateOptionsMenu();
            return 0;
        }
    } else {
        if (!AppManagerFragment.hideDeleteAllButton) {
            AppManagerFragment.hideDeleteAllButton = false;
            ((Activity) context).invalidateOptionsMenu();
            return tableSize;
        }
    }
}
Community
  • 1
  • 1
Timmiej93
  • 1,328
  • 1
  • 16
  • 35
  • Have you checked if your method onCreate is also called multiple times ? The problem must be outside your fragment. Where do you create it and how ? – Jack' Aug 08 '16 at 22:36
  • @Jack I just checked, `onCreateView` is only called once. I don't use `onCreate` in my fragments. This problem gets even worse when I have certain bits of code in my `onCreateOptionsMenu`, then it will run in an infinite loop, so I think it might still be something inside the fragments. – Timmiej93 Aug 09 '16 at 09:55

2 Answers2

6

These methods will be called whenever fragment either first creates or becomes visible and onResume, because onCreate is called even before onCreateView where all non ui things get initialized and calls to Activity is made. Hope it is clear why these two are calling super() of Parent Activity multiple times.

Now what to do to stop fragment from calling activity's onCreateOptionsMenu to inflate Menu layout again n again, declare this inside onCreate (overridden method) inside fragment.

setHasOptionsMenu(false);

If you want to have menu at activity as well but different menus for fragments then do

menu.clear(); 

Instead of calling super() from fragment's onCreateOptionsMenu()

If you just want to disable menu at Mainactivity try return false or simply remove onCreateOptionsMenu() from MainActivity.

As you said, launcher activity is a fragment so you want to disable menu for this fragment, so do something like this in this fragment:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

Then from onCreateOptionsMenu() inside same fragment disable and hide those menuItem.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
}

Even if this doesn't help, then try finding separate items of menu and disable them and set their visibility to false.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    if (menu != null) {
       menu.findItem(R.id.action_abc).setVisible(false);
       menu.findItem(R.id.action_xyz).setVisible(false);
    }
}

Hope i helped . !

mfaisalhyder
  • 2,250
  • 3
  • 28
  • 38
  • Hm, I probably should've said I need different kinds of menus depending on which fragment is being shown, so disabling the optionsmenu isn't really an option in the fragment. Should I disable it in the activity instead? – Timmiej93 Aug 08 '16 at 20:19
  • Yes i did it, disable it on main activity then as soon as user clicks fragment, inflate the menu and enable it. So for different fragemnts you will have different menus like whatsapp and other apps – mfaisalhyder Aug 09 '16 at 09:54
  • How do you exactly disable the optionsmenu on the Main Activity? I tried `setHasOptionsMenu`, but that doesn't work in the activity for some reason. – Timmiej93 Aug 09 '16 at 09:57
  • One more thing if you want to have menu at activity as well but different menus for fragment then do as i have edited in my answer. – mfaisalhyder Aug 09 '16 at 09:58
  • I tried clearing the menu, but I still get two. When I add `setHasOptionsMenu(false)` to my fragment, it simply doesn't have a menu, which isn't what I want either, unfortunately. – Timmiej93 Aug 09 '16 at 14:34
  • I only have the `onCreate()` method itself in my `MainActivity`, no other `onCreate....()` method, so I'm not sure why it's not working then (the screen that shows when the app starts is also a fragment, not the main activity. MA is never shown). – Timmiej93 Aug 09 '16 at 15:01
  • I don't think hiding stuff from the menu is the correct solution for this problem, it's more like a workaround. I found the issue to be related to the `RecyclerView` I'm using, so I updated my question. – Timmiej93 Aug 09 '16 at 18:43
2

This one was my own fault. I was invalidating the options menu in the getItemCount() method of my RecyclerViewAdapter, which obviously runs when the fragment is initiated. You can check out the question for the code that contains my error. Thanks for the help/suggestions all.

Timmiej93
  • 1,328
  • 1
  • 16
  • 35