0

Most of the times whenever there is a talk of updating the ActionBar options (like displaying/hiding items) I see people doing that with calling invalidateOptionsMenu method (or AppCompat equivalent) to force that onCreateOptionsMenu again, which essentialy does the same thing it did before which is inflating the menu again, setting up all the menu items etc. All this work, just to change a visibility of say... one item.

Same thing I see in all the samples I've seen from Google. And for the life of me I cannot figure out the reason why all this uneceseary overhead is done(inflating the menu etc) when all of this could be done if you only holded the Menu reference localy, and invoke a custom method say... adjustMenu(Menu menuReference), which would not have to inflate the menu and create it again, but just make neceseary modifications on the already created Menu. So something of these sorts: https://stackoverflow.com/a/7066901/905938

Most likely there is a reason for doing it Google way (through forcing onCreateOptionsMenu again and again), since Google samples do the same, but since I couldn't figure out the reason on my own, maybe someone could give me a hand here, and point me to that reason.

Community
  • 1
  • 1
Lucas
  • 3,521
  • 3
  • 27
  • 39

1 Answers1

1

You should only really be inflating your options menu within onCreateOptionsMenu().

when all of this could be done if you only holded the Menu reference localy

You can do this locally via the method onPrepareOptionsMenu(Menu menu). This would actually be a great place to set a menu item's visibility. As to the question of the significance to the call invalidateOptionsMenu(); it's purpose should be looked at from two viewpoints.

Before API 11 and the introduction of fragments, the call to invalidateOptionsMenu would signal that the methods onCreateOptionsMenu() and onPrepareOptionsMenu() should be called again. Since activities normally have only one options menu, the menu object could afford to be kept in memory so as to make subsequent calls to onCreateOptionsMenu() more responsive.

Since the release of API 11, the options menu could no longer be stored in memory as before, since the introduction of fragments meant that the activity as well as each of its fragments could have its own options menu, and as fragments can be changed dynamically during the lifetime of the activity, it would be inefficient to store a bunch of options menus for each fragment as these fragments would not be guaranteed to stay on screen. Remember as well that in API 11+, options menu items can be displayed on the action bar. Changing your phone's configuration from portrait to landscape would mean more options menu items could be displayed on the action bar, thus items present in the overflow menu could now be moved to the action bar itself. An alternate albeit slower solution would be to simply rebuild all onscreen fragments' options menus from scratch. So for API 11+, the call to invalidateOptionsMenu() can be viewed as a signal to indicate that the layout of an activity's fragments have changed, and that the methods onCreateOptionsMenu() and onPrepareOptionsMenu() should be called for both the activity and the fragments it is currently hosting.

Check out the entry on invalidateOptionsMenu(Activity activity) here for more information as to why invalidateOptionsMenu is used.

ZakDaniels99
  • 505
  • 4
  • 9
  • In the section you referred to, there is nothing as to why this method is called(which in effect forces onCreateOptionsMenu method on 11+ systems) instead of storing Menu reference locally and operating on that reference instead. – Lucas Nov 22 '14 at 16:46
  • Just added further explanation to invalidateOptionsMenu, hope this helps. – ZakDaniels99 Nov 22 '14 at 19:23
  • Ok, thanks to you I learned something I didn't before. I've tracked down a tutorial which make me realise that I had a wrong understanding of what Fragment's onCreateOptionsMenu does. It does not replace the Activity's created menu, it adds to it (at least that's the default behaviour). So now it makes more sense to call invalidate on the menu, however I'm not sold just yet. I'm not sold because due to the thing I found out, now I know that the Menu reference stays in fact the same, no matter how many fragments there is. But... since you pointed me to the right direction, the ckeck is yours. – Lucas Nov 22 '14 at 22:21