MenuItem not setting visibility properly - android

I get the menu item and then i try to set the visibility but the menu item is always shown. Can anyone see where I am making a mistake?
The menu item is not null and thus is allocated so thats not it.
MenuItem done = menu.findItem(R.id.action_done);
//animate the list view
if (isListEditing) {
done.setVisible(true);
menuItem.setTitle(this.getString(R.string.EditKey));
isListEditing = false;
adapter.endEdit();
} else {
done.setVisible(false);
menuItem.setTitle(this.getString(R.string.DoneKey));
isListEditing = true;
adapter.makeEditable();
}
this.invalidateOptionsMenu();
I get the menu reference here:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_test_results, menu);
this.menu = menu;
return true;
}
Update:
I was under the impression that you had to invalidate the options menu after you made an edit. But that is what was cause the edits to not go through.

According to the docs, what invalidateOptionsMenu() does is:
Declare that the options menu has changed, so should be recreated. The onCreateOptionsMenu(Menu) method will be called the next time it needs to be displayed.
That means onCreateOptionsMenu will get called again, inflating your original menu layout, and thus discarding your previous changes to the menu items visibility.
The recommended approach to modify the menu content dynamically is to use onPrepareOptionsMenu. So whenever you need to update menu items, you can call invalidateOptionsMenu(), and then inside onPrepareOptionsMenu, you set the menu items visibility.

There is no need for
this.invalidateOptionsMenu();
Take that off and it should work fine.

Related

Why my MenuItem is not being hidden?

I am trying to hide a MenuItem of my menu but without success.
This is the code that I have right now:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu){
MenuItem item = menu.findItem(R.id.lastOption);
item.setVisible(false);
invalidateOptionsMenu();
return true;
}
but it still shows that option when I run the application.
Trying to find why this behaviour happened, I tried to set some breakpoints to my code and found that menu variable has a variable called mVisibleItems. In that variable I can see that the item that I tried to hide does not appear. It appears on the application, though.
So, I cannot understand why if it does not appear on the menu visible variables, it still is shown on the application.
Am I missing something?
Thanks in advance!
invalidateOptionsMenu();, calls onCreateOptionsMenu again. From the documentation
Declare that the options menu has changed, so should be recreated. The
onCreateOptionsMenu(Menu) method will be called the next time it needs
to be displayed.
so, after setting your item to false, you are inflating the layout of your menu, again
I suppose that this is not the better way to do this but I could not do it using onPrepareOptionsMenu.
As I need two types of menu depending of the user that had logged in (admin or user) I finally do this creating two types of menu for my application. One with some options and one without the options that I do not need for a normal user. Then, on onCreateOptionsMenu I inflate the menu that I need depending of the user that has logged in.
This is the code:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
if("admin".equals(typeUser)){
getMenuInflater().inflate(R.menu.activity_main_admin, menu);
}else{
getMenuInflater().inflate(R.menu.activity_main_user, menu);
}
return true;
}
where typeUser is a String that I send from the Login Activity in which I set a bundle depending of the user that has logged in.
I also have created two activity_main layouts changing the menu option of the NavigationView on the XML:
app:menu="#menu/activity_main_admin" or app:menu="#menu/activity_main_user", depending on the layout.
Finally, I also have created a condition to set the layout on the onCreate method of MainActivity depending of the user that has logged in. This is the code to do this:
if("admin".equals(typeUser)){
setContentView(R.layout.admin);
}else{
setContentView(R.layout.user);
}

How to NOT call onCreateOptionsMenu when calling FragmentManager.replace()

I have a Toolbar being used as an ActionBar with two items. I only want to ever display one at a time as they kind of replace each other. The problem is that when i replace a Fragment, it call onCreateOptionsMenu and will inflate the menu again, meaning that the same action button will be shown, even if the other one was previously in the ActionBar. I have to need to change anything in the ActionBar from my Fragments or when a new Fragment is displayed(with FragmentManager.FragmentTransaction.replace()). So my question is how do I not call onCreateOptionsMenu when a new fragment is displayed?
I can't use a boolean because I will still need it to reinflate on orientation change. And any advice on how to handle orentation change for my situation?
I can post code, but it seems more conceptual and I'm not sure that it would help.
I solved the problem by instead of not calling onCreateOptionsMenu, I added the items to my menu manually.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean refreshVisible;
if (refreshItem != null && refreshItem.isVisible()){//is being displayed prior to inflation
refreshVisible = true;
}else if (refreshItem == null){//it's null so the menu has never been created
refreshVisible = true;
}else {//it's not null and invisibe, other icon was being displayed
refreshVisible = false;
}
menu.clear();//clear menu so there are no duplicate or overlapping icons
getMenuInflater().inflate(R.menu.main, menu);//inflate menu
refreshItem = menu.findItem(R.id.refresh);
useDataItem = menu.findItem(R.id.use_data);
refreshItem.setVisible(refreshVisible);//if menu is being created for first time or item was previously visible, then display this item
useDataItem.setVisible(!refreshVisible);//display this item if not displaying other
return true;
}
I would fiddle with the onPrepareOptionsMenu hook. If you can detect that your menu should not be shown you should jest return false from there. Per documentation:
Prepare the Screen's standard options menu to be displayed. This is called right before the menu is shown, every time it is shown. You can use this method to efficiently enable/disable items or otherwise dynamically modify the contents.
and
You must return true for the menu to be displayed; if you return false it will not be shown.
You can call setHasOptionsMenu(false); inside your fragment.
This will prevent onCreateOptionsMenu() from being called when that fragment added.

Refresh actionbar item icon

This works just fine but If I'm on a different activity and I use the back button, it won't update the action bar because the activity is already created and it won't update the action bar. Already tried to use supportInvalidateOptionsMenu() on the on_create method but it didn't work.
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
Cursor cursor = messages.getMessages();
if(cursor.getCount()>0){
inflater.inflate(R.menu.actionbar1, menu);
}else{
inflater.inflate(R.menu.actionbar2, menu);
}
return super.onCreateOptionsMenu(menu);
}
As the documentation for onCreateOptionsMenu(Menu) states:
This is only called once, the first time the options menu is
displayed. To update the menu every time it is displayed, see
onPrepareOptionsMenu(Menu).
So going back to an already created Activity does not trigger onCreateOptionsMenu(Menu) again.
What I suggest you to do is create just one menu containing all the menu items and selectively activate/deactivate them in onPrepareOptionsMenu(Menu) based on one or more flags. Then put invalidateOptionsMenu() in onResume() which is called every time the Activity is shown.
Hope it helps
Try calling invalidateOptionsMenu whenever you need to change the icon.
It will destroy your menus and re-inflate them by calling onPrepareOptionsMenu.

Changing Action Bar Menu Tab Label

I want to change one of my Action Bar Menu Tab Labels depending on the state of a variable in my code. I found the following that describes how to use onPrepareMenuOptions() for this purpose, but my problem is that onPrepareMenuOptions() is being called after I change the variable that controls the label state.
How can I alter a MenuItem on the Options Menu on Android?
As specific as I can be, I have a dialogFragment that's brought up when the user selects the relevant Action Bar item. The dialog allows the user to change a parameter, and depending on value selected, I want to change the AB item label (but not the code associated with either the AB item or the dialogFragment it starts up.
Is there something I should be doing (perhaps in the dialog's onDismiss() method) to force my application to call onPrepareMenuOptions()??
In response to Nate's request, my activity has the following code:
public boolean onCreateOptionsMenu (Menu menu)
{
getMenuInflater().inflate (R.menu.app_menu, menu);
this.abMenu = menu;
this.varTab = abMenu.findItem (R.id.menu_varTab);
// Need to be able to change this label
return super.onCreateOptionsMenu (menu);
}
#Override
public boolean onPrepareOptionsMenu (Menu menu)
{
varTab.setTitle (0 == importantVariable
? ("Set Var")
: ("Set Var\n" + String.valueOf (importantVariable)) + " units");
return super.onPrepareOptionsMenu (menu);
}
Following good advice, I added act.invalidateOptionsMenu() to the onDismiss() method of the dialogFragment associated with this menu item, and now the onPrepareOptionsMenu() is called when it should.
On Android 2.3.x and lower, the system calls onPrepareOptionsMenu() each time the user opens the options menu (presses the Menu button).
On Android 3.0 and higher, the options menu is considered to always be open when menu items are presented in the action bar. When an event occurs and you want to perform a menu update, you must call invalidateOptionsMenu() to request that the system call onPrepareOptionsMenu().
I believe - if you are using tabs in your action bar, that something like this should work:
bar.getTabAt(0).setText("Some new Sequence");

Why isn't MenuInflater Responding?

I am a noob to android and i am trying to inflate two different menus depending on user selection. However, the menu isn't switching. The same menu inflates everytime regardless of what the user selects. I've tried and checked my if/else statmente with various parameters and the menu inflater still doesn't respond properly by only inflating the same menu. Any help is greatly appreciated.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
popUpMenu = getMenuInflater();
//popUpMenu.inflate(R.menu.cool_menu, menu);
if(mypodcast==null){
popUpMenu.inflate(R.menu.cool_menu, menu);
}else {
popUpMenu.inflate(R.menu.podcast, menu);
}
return true;
}
The same menu inflates everytime regardless of what the user selects.
That is because onCreateOptionsMenu() is not called each time you open the menu, from the documentation:
This is only called once, the first time the options menu is displayed. To update the menu every time it is displayed, see onPrepareOptionsMenu(Menu)
If you want to change menus you need to do this in onPrepareOptionsMenu(). However I don't believe that you can or should inflate a new menu every time onPrepareOptionsMenu() is called. But you can combine the two menus and change the visibility of each menu item according to what you want in this method.

Categories

Resources