8

I had a problem setting up some fragment menu items in the ActionBar and I found a way to solve it, but I don't understand why it worked.

I wanted to change the visibility in a menu item right after I inflated it from a menu xml file in onCreateOptionsMenu method. The code seems to work fine, but there's no visible effect. I solved the problem inflating the menu in onCreateOptionsMenu method but changing the visibility of it in onPrepareOptionsMenu method.

What I want to know is why changing the visibility in onCreateOptionsMenu does not work.

What can I do in onPrepareOptionsMenu that I can't do in onCreateOptionsMenu?

Is there any pattern to follow here?

Thanks!

Here's the relevant code, just in case:

public class MyFragment extends Fragment {

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.my_menu, menu);

        // This does not work, compiles and runs fine, but has no visible effect
        MenuItem someMenuItem = menu.findItem(R.id.some_menu_item);
        someMenuItem.setVisible(false);
    }

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

        // This does work
        MenuItem someMenuItem = menu.findItem(R.id.some_menu_item);
        someMenuItem.setVisible(false);
    }
}
Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53
Gerardo Contijoch
  • 2,421
  • 5
  • 20
  • 29
  • 1
    I'm not sure, but the [documentation](http://developer.android.com/reference/android/app/Activity.html#onCreateOptionsMenu(android.view.Menu)) says: "_…To update the menu every time it is displayed, see [onPrepareOptionsMenu(Menu)](http://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu(android.view.Menu))._" –  Jul 07 '12 at 15:02
  • 1
    Thanks for the comment! The thing here is I don't need to 'update it every time it's displayed' (it's displayed all the time, there are no submenues), I just want to configure the menu only once, when created/inflated and that's all. All right, it may seem the same thing in my situation but the point of my question is understand why does it work like this. Why do I have to 'reconfigure' the menu every time it's displayed when I can do it only once when I create it? – Gerardo Contijoch Jul 07 '12 at 15:13
  • I understand and agree that should be an option. However in my opinion, I think it's the way Android works. In some cases, you can hardcode the menu's properties with xml attributes. –  Jul 07 '12 at 17:01

4 Answers4

6

You should call super.onCreateOptionsMenu(menu, inflater); after you have created your menu, not before. That sends the menu up in the hierarchy and other fragments or the activity may want to add items themselves.

The activity is responsible for the displaying and managing the menu, so if you change the visibility after it has been sent to the activity, nothing much is going to happen.

Now, when you call super.onPrepareOptionsMenu(menu); it will "prepare" it's menu, but it will now take the changes you've made in the onCreateOptionsMenu into account.

Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53
Christian
  • 1,155
  • 8
  • 13
0

May be the code should return true to make the menu visible, that means you should put return true; statement in both onCreateOptionsMenu() and onPrepareOptionsMenu().

Hope this helps.

bool.dev
  • 17,508
  • 5
  • 69
  • 93
r3d
  • 71
  • 3
  • 8
  • 5
    onCreateOptionsMenu returns void – Axarydax Sep 22 '13 at 18:00
  • 1
    Actually, there are TWO onPrepareOptions() methods. The [first](http://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu(android.view.Menu)), for the Activity class, does return a value-- if true is not returned, the menu won't show. The [Fragment](http://developer.android.com/reference/android/app/Fragment.html#onPrepareOptionsMenu(android.view.Menu)) version does not. The Fragment version requires API 11 vs API 1 for the Activity version. Kind of interesting. – fattire May 23 '15 at 23:18
0

I use the onPrepareOptionsMenu to update which items on the menu should be active and which ones should be grayed out/removed depending on the current state of the activity. Use the setVisible method of the menu item to control whether it is currently shown on the menu or not.

Howard
  • 101
  • 1
-2

This works for me

public class ContentFragment extends android.support.v4.app.Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.content_frame,container,false);
    setHasOptionsMenu(true);
    return v;
}

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

Try it

Dipti Agravat
  • 39
  • 1
  • 10