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);
}
Related
I am having Viewpager with 3 fragments. I want to show menu in only one of the fragments.
1st, I don't know why toolbar.inflateMenu doesn't work.
2nd, the menu works, if I have onPrepareOptionsMenu method and do
getMenuInflater().inflate(R.menu.add_user, menu); but the menu is displayed in all the fragments.
So, according to other questions in stack overflow, I implemented the below code, but it doesn't show the menu, it enters the method but menu is not shown.
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
//getMenuInflater().inflate(R.menu.add_user, menu);
info("Menu=>${tabs_viewpager.currentItem}")
val menuItem = menu?.findItem(R.id.addUserMenu)
menuItem?.setVisible(tabs_viewpager.currentItem == 1)
return true
}
The control comes to this method and shows currentItem. But it doesn't display the menu. Menu is there with id. Can someone direct me what can I correct to get this work?
try calling setHasOptionsMenu(true); in oncreate() of the fragments where you want the menu to show (you can set it to false in the fragments where you do not want the menu to show).
also include:
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
// your code
}
in the fragments where you want to set/change the menu. this is called everytime before the menu is shown.
you can also call invalidateOptionsMenu() or supportInvalidateOptionsMenu() (if you're using the support library) to force onPrepareOptionsMenu(menu) to be called.
you may want to check out this menus tutorial
good luck
clive
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.
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.
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.
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.