Good Morning Guys,
i am trying to hide the option menu on some fragment.For the example i just want the option menu show on Promotion page
i add the code in the promotion.java
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
inflater.inflate(R.menu.toolbar_menu, menu);
super.onCreateOptionsMenu(menu,inflater);
}
and then i want to hide on other fragment.
when i launching the app and the first fragment is like
but when i click to the promotion page and click back to the menu page and the action bar will be like this
i am using getSupportFragment to call the menu item, and this problem just only happen on the fragment using the getSupportFragment call out.
case R.id.menu:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MenuFragment()).addToBackStack(null).commit();
If you want to control the option menu from Fragment you must call setHasOptionsMenu(true) in onCreate() of the Fragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Clear the menu fromonCreateOptionsMenu():
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
}
OR, you can show/hide specific menu item by overriding onPrepareOptionsMenu:
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem item = menu.findItem(R.id.your_menu_item);
item.setVisible(false);
}
In the fragment onCreate add setHasOptionsMenu(true)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
then
#Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem item=menu.findItem(R.id.action_search);//your id instead of action_search
item.setVisible(false);
}
I using menu drawer which has more Fragments. In some Fragments I have menu item REFRESH but in some fragments I want hide this menu item (I don't want show menu but I don't want hide ActionBar).
I try add override onCreateOptionsMenu() to Fragment where I don't want show this menu item but I can not get it to work. I try many way see commented line in code. Does any idea where is problem? And last this menu item go to hide when I activate menu drawer when is called onPrepareOptionsMenu() in MainActivity but I need do this when I'm in Fragment.
Fragment where I want hide menu item REFRESH:
public class FindPeopleFragment extends Fragment {
public FindPeopleFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_find_people, container, false);
//setHasOptionsMenu(false);
return rootView;
}
private Menu menu=null;
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.main, menu);
this.menu=menu;
menu.findItem(R.id.refresh).setVisible(false);
getActivity().invalidateOptionsMenu();
//setHasOptionsMenu(false);
super.onCreateOptionsMenu(menu,inflater);
}
}
MainActivity where is defined MENU DRAWER:
//Slide menu item click listener
private class SlideMenuClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// display view for selected nav drawer item
displayView(position);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// toggle nav drawer on selecting action bar app icon/title
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch (item.getItemId()) {
case R.id.refresh:
Toast.makeText(this, "Refreshing data...", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
// Called when invalidateOptionsMenu() is triggered
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.refresh).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
In the fragment where you want to hide the Item
#Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem item=menu.findItem(R.id.action_search);
if(item!=null)
item.setVisible(false);
}
and in onCreate() of your fragment
setHasOptionsMenu(true);
In the Fragment where you don't want to show any menu options, you need setHasOptionsMenu(false); in the onCreate(), like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
}
However, the menu that is being shown that you would like to hide (REFRESH), belongs to MainActivity. That is why it is always shown. Since you want to control the menu at the Fragment level (and not show an Activity options menu), my suggestion is to delete the menu code from the Activity and implement it in your Fragment.
Activitys and Fragments can each have their own separate menus. See this link.
please try this
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
}
and put this on your fragmen's onCreate()
setHasOptionsMenu(true);
In Fragment Class
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
}
in Kotlin for those who needs it
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
menu.clear()
}
I used the code below for hiding menu items in a fragment where I don't want to use it.
Note: Please read comment
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
Fragment whichFragment=getVisibleFragment();//getVisible method return current visible fragment
String shareVisible=whichFragment.getClass().toString();
if(shareVisible.equals(AccFragment.class.toString())
||shareVisible.equals(SocFragment.class.toString())
||shareVisible.equals(DevFragment.class.toString())
){
MenuItem item=menu.findItem(R.id.action_share);
item.setVisible(false);
}
return super.onCreateOptionsMenu(menu);
}
in Kotlin
override fun onPrepareOptionsMenu(menu: Menu) {
val item: MenuItem = menu.findItem(R.id.action_search)
item.isVisible = false
}
in onCreate() of your fragment
setHasOptionsMenu(true)
There are many different versions of similar solutions but unfortunately, none of them worked for me. I am sharing what eventually was useful for me to hide the whole overflow menu with multiple menu items. Thought maybe it's useful for anyone.
I grouped my menus with an id and then referred that id
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(R.id.menu_overflow, false);
super.onPrepareOptionsMenu(menu);
}
If you want to hide any individual menu item then you can use
menu.getItem(R.id.action_licenses).setVisible(false);
Important thing is that you should have setOptionsMenu(true) in onViewCreated()
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
Call setHasOptionMenu(true) in onCreateView()
and Do not call super.onCreateOptionsMenu() in fragment's onCreateOptionMenu() instead call menu.clear() because this will override the existing menu with the activity's menu
This worked in my case.
Or solve it in the same Fragment which created the menu, if you host the Actionbar on Activity level. This way you don't have to add it on every other Fragment where you don't want to show it:
public override void OnDestroy()
{
base.OnDestroy();
HasOptionsMenu = false;
}
Add these functions to your Fragment
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem item=menu.findItem(R.id.delete);
item.setVisible(false);
}
Firstly in your Activity that has the toolbar, create a method that sets up the overflow menu for you:
public void setUpOptionMenu(Toolbar toolbar){
this.setSupportActionBar(toolbar);
}
In your fragments onCreateView() method, get the reference of your current activity and call your activities setUpOptionMenu() method:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
...
...
public void ((YourActivityName)this.getActivity()).setUpOptionMenu(null);
...
...
}
Cheers!!!
Overrride the following method just in your fragment and it will do the trick.
#Override
public void onCreateOptionsMenu(Menu menu,MenuInflater inflater) {
// Do something that differs the Activity's menu here
getActivity().getMenuInflater().inflate(R.menu.drawer, menu);
}
2022 KOTLIN
On your activity, where you navigate to fragments, You can try like below, On below code, Tested on Side Navigation view, It has been shown wherever needed using toolbar.inflateMenu(R.menu.toolbar_menu) and hidden using toolbar.menu.clear() on toolbar reference.
binding.naviSideNav.setNavigationItemSelectedListener(NavigationView.OnNavigationItemSelectedListener {
when (it.itemId) {
R.id.side_nav_home->{
toolbar.title=""
toolbar.menu.clear()
toolbar.inflateMenu(R.menu.toolbar_menu)
toolbar.setBackgroundColor(ContextCompat.getColor(this,R.color.home_screen_bg))
navController.navigate(R.id.navigation_home)
}
R.id.side_nav_appointments->{
}
R.id.side_nav_ehr->{
}
R.id.side_nav_invoices->{
}
R.id.side_nav_settings->{
toolbar.title=getString(R.string.nav_menu_Settings)
toolbar.menu.clear()
toolbar.setBackgroundColor(ContextCompat.getColor(this,R.color.home_screen_bg))
navController.navigate(R.id.navigation_settings)
}
R.id.side_nav_logout->{
}
}
binding.dlt.closeDrawer(GravityCompat.START)
true
})
Clean and redraw menu item
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
menu.clear()
inflater.inflate(R.menu.main_menu, menu)
menu.findItem(R.id.id_menu_search)?.isVisible = true
super.onCreateOptionsMenu(menu, inflater)
}
I have checked the answers but now the optionMenu has been deprecated in the latest Android api level
setHasOptionsMenu(false)
so for the people who are using MenuProvider for optionMenu can use the
setMenuVisibility(false)
like this in fragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setMenuVisibility(false)
}
Just find the item you want to hide using findItem then set its visibility to false.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.action_settings);
item.setVisible(false);
}
I have a listview and call detail activity when the item is selected.
My onCreateOptionsMenu has error on displaying the menu at Action Bar.
public boolean onCreateOptionsMenu(Menu menu) {
new MenuInflater(getActivity()).inflate(R.menu.detail_view_menu, menu);
return (super.onCreateOptionsMenu(menu));
}
The error is The method onCreateOptionsMenu(Menu, MenuInflater) in the type Fragment is not applicable for the arguments (Menu). Error happened at return line.
I implement listview and detail activity using fragmentTransaction.
Thanks
Your onCreateOptionsMenu(Menu menu) just needs to be in the activity that hosts the fragment, not in the fragment itself.
You could also consider extending a BaseActivity and including it in there just once.
public class BaseActivity extends Activity {
public boolean onCreateOptionsMenu(Menu menu) {
new MenuInflater(getActivity()).inflate(R.menu.detail_view_menu, menu);
return (super.onCreateOptionsMenu(menu));
}
}
public class ListActivity extends BaseActivity {
// ...
}
public class DetailActivity extends BaseActivity {
// ...
}
Try it like this but put it in your main Activity class:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.detail_view_menu, menu);
return true;
}
OR if you want your Fragment to add items to the ActionBar you have to use a slightly different construct:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.detail_view_menu, menu);
}
You have an additional parameter that you have to add(MenuInflater). Also, in a Fragment the onCreateOptionsMenu doesn't return a boolean value.
Now that you have your inflater you need to call setHasOptionsMenu(true) in your Fragment's onCreate() method. Otherwise your items will not be displayed in the ActionBar.
Your Fragment code, handling the menu inflation, should now look like this:
public class DetailFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.detail_view_menu, menu);
}
}
I have a fragment with that needs to build its own action bar :
public class CalendarFragment extends Fragment {
public CalendarFragment() {
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().supportInvalidateOptionsMenu();
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.calendar_menu1, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER);
textView.setText("Calendar Fragment");
return textView;
}
}
the problem is it doesnt create a new menu with items from calendar_menu1 but just adds the items from it to the old menu, as if invalidateOptionsMenu doesnt work (i tried getActivity().invalidateOptionsMenu() too)
You must call in onCreate():
setHasOptionsMenu(true);
It is normal, looking into the javadoc of the MenuInflater, "The items and submenus will be added to this Menu":
public void inflate (int menuRes, Menu menu)
Inflate a menu hierarchy from the specified XML resource. Throws InflateException if there is an error.
Parameters
menuRes Resource ID for an XML layout resource to load (e.g., R.menu.main_activity)
menu The Menu to inflate into. The items and submenus will be added to this Menu.
Did you try to call menu.clear() before to inflate your fragment menu?
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.calendar_menu1, menu);
}
Is that possible to have different menus for each tab of TabHost?
Yes, you can in onCreateOptionsMenu depending on the tab inflate a different menu
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
int tab = getTabHost().getCurrentTab()
if (tab==1)
inflater.inflate(R.menu.main_menu, menu);
else
inflater.inflate(R.menu.other_menu, menu);
return true;
}
You need to provide different versions of menu.xml files within res/menu for this.
If you're using fragments you can put setHasOptionsMenu(true); inside onCreate method of your fragment and override onCreateOptionsMenu.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_xxx, menu);
}