How to create option menu in Fragment? - android

I am working on a code where I need to create a option menu, I have followed some tutorials about how to implement this menu on fragment activities, but for some reason the code that I'm working with does not show the menu. Does anyone knows what could be?
ProfileFragment
public class ProfileFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_profile, container, false);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.profile_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.edit_profile:
break;
case R.id.change_password:
break;
case R.id.log_out:
break;
}
return super.onOptionsItemSelected(item);
}
}
XML
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#10c0bd"
android:minHeight="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark" />

Possible its because you trying to set setHasOptionsMenu(true); on OnCreate instead of OnCreateView.
Try to delete setHasOptionsMenu(true); from OnCreate and add it in OnCreateView

Try this,
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.profile_menu, menu);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}

First of all Override Create Method in Fragment and write setHasOptionsMenu(true)
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Then after override OnPrepareOptionMenu method in Fragment and Write code which i place inside it.
I hide my Search Menu only. Similarly You can hide all menu item or selective item as per your choice.
#Override
public void onPrepareOptionsMenu(Menu menu) {
MenuItem item=menu.findItem(R.id.menu_search);
if(item!=null)
item.setVisible(false);
}

Related

Unable to receive click on menu items in Fragment

I'm having a ToolBar made as ActionBar in a Fragment. I'm able to add ActionBar menu items but I'm not able to receive click response when I click on any ActionBar menu item.
I have read a lot of similar questions, I tried all but I'm still facing issue, so asked a question here.
The Fragment
public class DetailFragment extends Fragment {
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
setHasOptionsMenu(true);
return inflater.inflate(R.layout.project_detail, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mToolBar = (Toolbar)view.findViewById(R.id.tb_toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(mToolBar);
mToolBar.setTitle(R.string.project_details);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.project_detail_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options:
// do something
break;
}
return true;
}
In my case in code above, onOptionsItemSelected is not even getting called.
Any pointers why ?
The Activity where I'm inflating this Fragment -
public class TestJust extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_just);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, new ProjectDetailFragment());
ft.commit();
}
}
project_detail_menu.xml -
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="#+id/options"
android:title="options"
android:icon="#android:drawable/ic_menu_more"
app:showAsAction="always"/>
</menu>
Most probably your problem is that you're always returning true from the activity's onOptionsItemSelected method.
When you return true, you consume the click event inside the method in the activity, that's why the click event never reaches the onOptionsItemSelected method inside your fragment.
Try this
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear()
inflater.inflate(R.menu.project_detail_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options:
// do something
return true;
default:
return super.onOptionsItemSelected(item);
}
Solution:
You are calling setHasOptionsMenu(true); in onCreateView()
Please call that method in onCreate()
Like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Calling this method in onCreate() ensures that the menu must participate in Fragment.
Then,
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu_items, menu);
}
Finally,
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options:
// do something
break;
}
return super.onOptionsItemSelected(item);
It should work now.
initialize option in onCreateOptionMenu then check it. you only inflate menu, use without initialize option, first initialize then use it.
like: MenuItem item = menu.findItem(R.id.option);
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
MenuItem item = menu.findItem(R.id.option);
}
switch (item.getItemId()) {
case R.id.options:
// do something
return true;//<- Here you need to return true because breaking compile from this line returns default false;
default:
return super.onOptionsItemSelected(item);
}

Menu not visible in Fragment

I have a fragment that contains menu I have tried calling setHasOptionsMenu(true); in both onCreate() as well as onCreateView() and set a toolbar as my Actionbar. I have gone through all the questions about the same here but none of the solutions seem to be working for me! I have tried changing the theme, menu.clear(), and returning true from onCreateOptions() of the Activity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
// Inflating view layout
layout = inflater.inflate(R.layout.side_panel, container,false);
toolbar = layout.findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
return layout;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_side_panel,menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
If you have declared Toolbar in the XML file, Then try this
First get a reference to Toolbar using findViewByid() then inflate your menu
mToolbar.inflateMenu(R.menu.main_menu);

Action bar menu item not working in fragment

I am working on a navigation drawer in which i am using multiple fragment .In one of the fragment i have to use menu item for some action .Now i can inflate menu item on action bar on that fragment but action is not performing .
public class Location extends Fragment implements View.OnClickListener {
GoogleMap googleMap;
Fragment fragment;
Button arrived_mbtn;
TextView current_mtv,request_mtv;
LinearLayout btn_mlayout,journey_mlayout;
View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_location, container, false);
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("you are in oncreate", "dfsdfsd");
setHasOptionsMenu(true);
}
#Override
public void onDestroyView() {
// TODO Auto-generated method stub
try {
if (fragment != null) {
fragment = getFragmentManager().findFragmentById(R.id.map);
FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
} catch (Exception e) {
e.printStackTrace();
}
Thread.interrupted();
super.onPause();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
getActivity().getMenuInflater().inflate(R.menu.menu_payment_card_detail,menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId())
{
case R.id.action_settings:
Toast.makeText(getActivity(),"hello",Toast.LENGTH_SHORT);
return true;
}
return super.onOptionsItemSelected(item);
}
}
by this code an item is inflate on action bar but on click it did,t show any thing .
Change like this. You have not called show() on toast.
case R.id.action_settings:
Toast.makeText(getActivity(),"hello",Toast.LENGTH_SHORT).show();
Change your onCreateOptionsMenu method as below.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_payment_card_detail,menu);
}
And whatever id you have applied to your menu item, use that in the condition to check whether that menu item is clicked or not.
in your code:
Move the setHasOptionsMenu(true) in the onCreateView() method;
Use inflater.inflate(R.menu.menu_payment_card_detail,menu); in the
onCreateOptionsMenu method.
Something like this:
#Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_payment_card_detail,menu);
super.onCreateOptionsMenu(menu, inflater);
}
Add the show() method to your Toast Toast.makeText(getActivity(),"hello",Toast.LENGTH_SHORT).show();
In fragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set setHasOptionsMenu
setHasOptionsMenu(true);
}
Check the parent activity doesn't eat the item selected, i.e. make sure if the parent activity implements onOptionsItemSelected() that it returns false for your fragment's items.

toolbar menu item click in fragments

I know this question has been asked and but I am unable to solve my problem after looking at those answer. I have an Activity with a Fragment.
In fragment, I have added the toolbar and I want to handle toolbar menu item click events from the fragments.
In menu, I have added a single share button. I am getting the click event callback for the Up navigation (arrow home button) but I am not getting click event callback for the share button in my fragment.
Can some points me at what I am doing wrong here.
menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.rahul.haridasasampada.details.DescriptionActivity">
<item
android:id="#+id/action_share"
android:title="Share"
android:orderInCategory="100"
app:showAsAction="always"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider"/>
</menu>
I have added toolbar to the fragment layout.
My Activity's code -
public class DescriptionActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_description);
if (savedInstanceState == null) {
Article articleExtra = (Article) getIntent().getParcelableExtra(DescriptionFragment.ARGS_EXTRA);
DescriptionFragment descriptionFragment = DescriptionFragment.newInstance(articleExtra);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, descriptionFragment)
.commit();
}
}
#Override
protected void onResume() {
super.onResume();
getSupportActionBar().setTitle(R.string.app_name_in_kannada);
}
#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_description, menu);
Log.d("debug", "activity : onCreateOptionsMenu");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
Log.d("debug","activity: action home has clicked");
onBackPressed();
return false;
case R.id.action_share:
Log.d("debug","activity: action share has clicked");
return false;
}
return super.onOptionsItemSelected(item);
}
}
My Fragments code -
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// some code
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ActionBarActivity actionBarActivity = (ActionBarActivity) getActivity();
Toolbar toolbar = (Toolbar) getView().findViewById(R.id.toolbar_actionbar);
actionBarActivity.setSupportActionBar(toolbar);
toolbar.setOnMenuItemClickListener(this);
toolbar.inflateMenu(R.menu.menu_description);
}
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_share:
if (menuItem.getItemId() == R.id.action_share)
Log.d("debug","action share has clicked");
return true;
}
return false;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
Log.d("debug", "fragment : onCreateOptionsMenu");
MenuItem shareMenuItem = menu.findItem(R.id.action_share);
mShareActionProvider =(ShareActionProvider)MenuItemCompat.getActionProvider(shareMenuItem);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
Log.d("debug","fragment : action home has clicked");
return true;
case R.id.action_share:
Log.d("debug","fragment: action share has clicked");
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View detailFragmentView = inflater.inflate(R.layout.fragment_description, null);
return detailFragmentView;
}
From Android Docs, for Fragment:
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater)
Initialize the contents of the Activity's standard options menu. You should place your menu items in to menu. For this method to be called, you must have first called setHasOptionsMenu(boolean).
so you want to control actionbar menu in Fragment, then you have to call setHasOptionsMenu method better in Fragment's onCreate(...):
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
also important is that you should not use inflateMenu and onCreateOptionsMenu both together for same ToolBar, inflateMenu is for standalone without setting ToolBar as ActionBar.
Suggestion:
keep one ToolBar in Activity as ActionBar for your App, and another ToolBar standalone inside Fragment.
Hope this help!
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
public class MyFragment extends Fragment implements Toolbar.OnMenuItemClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list, container, false);
Toolbar toolbar= (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.menu_main);
toolbar.setOnMenuItemClickListener(this);
return rootView;
}
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_menu:
//do sth here
return true;
}
return false;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.training1_fragment, container,
false);
setHasOptionMenu(true);
return v;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_save :
{
//Write here what to do you on click
return true;
}
}
return super.onOptionsItemSelected(item);
}
You should getPointer toolbar from your activity class and inflate menu in fragment class.
You can look this ex:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
activity = ((DescriptionActivity ) getActivity());
Toolbar tollbar=getView.findViewById(R.id.your_toolbar);
activity.setSupportActionBar(toolbar);
activity.toolbar.inflateMenu(R.menu.menu_search);
activity.toolbar.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_search:
break;
}
return false;
}
Please refer this for click of the Fragment optionMenu click link.

onCreateOptionsMenu inside Fragments

I have placed setHasOptionsMenu(true) inside onCreateView, but I still can't call onCreateOptionsMenu inside fragments.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
return inflater.inflate(R.layout.facesheet, container, false);
}
Below is my onCreateOptionsMenu code.
#Override
public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) {
getSupportMenuInflater().inflate(R.menu.layout, menu);
return (super.onCreateOptionsMenu(menu));
}
The error message I get:
The method onCreateOptionsMenu(Menu) of type Fragment must override or implement a supertype method.
try this,
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_sample, menu);
super.onCreateOptionsMenu(menu,inflater);
}
Finally, in onCreateView method, add this line to make the options appear in your Toolbar
setHasOptionsMenu(true);
Your already have the autogenerated file res/menu/menu.xml defining action_settings.
In your MainActivity.java have the following methods:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_settings:
// do stuff, like showing settings fragment
return true;
}
return super.onOptionsItemSelected(item); // important line
}
In the onCreateView() method of your Fragment call:
setHasOptionsMenu(true);
and also add these 2 methods:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_1:
// do stuff
return true;
case R.id.action_2:
// do more stuff
return true;
}
return false;
}
Finally, add the new file res/menu/fragment_menu.xml defining action_1 and action_2.
This way when your app displays the Fragment, its menu will contain 3 entries:
action_1 from res/menu/fragment_menu.xml
action_2 from res/menu/fragment_menu.xml
action_settings from res/menu/menu.xml
I tried the #Alexander Farber and #Sino Raj answers. Both answers are nice, but I couldn't use the onCreateOptionsMenu inside my fragment, until I discover what was missing:
Add setSupportActionBar(toolbar) in my Activity, like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.id.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
I hope this answer can be helpful for someone with the same problem.
Call
setSupportActionBar(toolbar)
inside
onViewCreated(...)
of Fragment
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
((MainActivity)getActivity()).setSupportActionBar(toolbar);
setHasOptionsMenu(true);
}
Set setHasMenuOptions(true) works if application has a theme with Actionbar such as Theme.MaterialComponents.DayNight.DarkActionBar or Activity has it's own Toolbar, otherwise onCreateOptionsMenu in fragment does not get called.
If you want to use standalone Toolbar you either need to get activity and set your Toolbar as support action bar with
(requireActivity() as? MainActivity)?.setSupportActionBar(toolbar)
which lets your fragment onCreateOptionsMenu to be called.
Other alternative is, you can inflate your Toolbar's own menu with toolbar.inflateMenu(R.menu.YOUR_MENU) and item listener with
toolbar.setOnMenuItemClickListener {
// do something
true
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_add_customer, container, false);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_sample, menu);
super.onCreateOptionsMenu(menu,inflater);
}
You can do easily as,
inside your fragment on Create method,
setHasOptionsMenu(true)
and now you can override,
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
menu.clear()
}

Categories

Resources