(Deprecated) Fragment onOptionsItemSelected not being called
Solution 1
Edit for actionbar sherlock use
I had to use
public boolean onMenuItemSelected(int featureId, MenuItem item) {
in the main activity to capture the menu item
Solution 2
Same problems happened to me:
onMenuItemSelected events didn't get called in Fragment
Searched google cann't find a solution, and add onMenuItemSelected method in FragmentActivity doesn't solve it.
Finally resolve it by following reference to http://developer.android.com/guide/topics/ui/actionbar.html
Note: If you added the menu item from a fragment, via the Fragment class's onCreateOptionsMenu callback, then the system calls the respective onOptionsItemSelected() method for that fragment when the user selects one of the fragment's items. However the activity gets a chance to handle the event first, so the system calls onOptionsItemSelected() on the activity before calling the same callback for the fragment.
Which means only if you don't have that menu item handler in onOptionsItemSelected() on the activity, the onOptionsItemSelected() on the fragment will be called.
Code as following -----Remove the handler for R.action.add on FragmentActivity):
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
popBackStack();
return true;
case R.id.action_search:
searchAction();
return true;
case R.id.action_logout:
userLogout();
return true;
//case R.id.action_add:
//return true;
default:
return super.onOptionsItemSelected(item);
}
}
And the handler for R.action.add on Fragment looks like this:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d("onOptionsItemSelected","yes");
switch (item.getItemId()) {
case R.id.action_add:
add();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Finally, remember to add
setHasOptionsMenu(true);
in your onCreate method in Fragment
Solution 3
I had the same problem, but I think it's better to summarize and introduce the last step to get it working:
Add
setHasOptionsMenu(true)
method in your Fragment'sonCreate(Bundle savedInstanceState)
method.Override
onCreateOptionsMenu(Menu menu, MenuInflater inflater)
(if you want to do something different in your Fragment's menu) andonOptionsItemSelected(MenuItem item)
methods in your Fragment.Inside your Activity's
onOptionsItemSelected(MenuItem item)
method, make sure you returnfalse
when the menu item action would be implemented in Fragment'sonOptionsItemSelected(MenuItem item)
method.
An example:
Activity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.activity_menu_item:
// Do Activity menu item stuff here
return true;
case R.id.fragment_menu_item:
// Not implemented here
return false;
default:
break;
}
return false;
}
Fragment
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
....
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Do something that differs the Activity's menu here
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.activity_menu_item:
// Not implemented here
return false;
case R.id.fragment_menu_item:
// Do Fragment menu item stuff here
return true;
default:
break;
}
return false;
}
Solution 4
I have noticed that the solution people gave you was to implement the code for your menue item in the activity rather then the fragment. I think it will look much more orgenized if you had implemented the code in the fragment rather then the activity 'cos in my opinion it looks better. To do so, do as follows :
Activity
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.SomeIDInTheMenueOfTheActivity:
{
//something();
break;
}
default:
//do something default and add the code under :
return super.onOptionsItemSelected(item);
}
return true;
}
Fragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.SomeIDInFragmentMenue:
{
break;
}
default:
return super.onOptionsItemSelected(item);
}
return true;
}
Now the lines (and the likes): "return super.onOptionsItemSelected(item);" in the activity and fragment are super important, because as if you will follow the code in debug, you will see that the menue events functions will be called first on the Activity, and if the item did not match the id's in the activity's switch-case, the degault line : "super.onOptionsItemSelected(item);" will call the onOptionsItemSelected function on the fragment, as we wanted. (if you have many fragments, make sure to have that line in them as well, as the calling hirarchy can be somewhat complicated).
Solution 5
it's so simple you can do that in your fragment to make sure that your action will listen correctly:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Related videos on Youtube
user1634451
Updated on July 05, 2022Comments
-
user1634451 almost 2 years
EDIT: This question was for the deprecated sherlock action bar. Android support library should be used instead now
I have added an action bar menu option called share for my
fragment
which appears but the selection event is not being caughtI am adding it like this
@Override public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) { MenuItem item = menu.add(0, 7,0, R.string.share); item.setIcon(R.drawable.social_share).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); }
Trying to capture it in both the
fragment
and thefragment activity
like@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case 7: Intent share = new Intent(Intent.ACTION_SEND); share.setType("text/plain"); share.putExtra(Intent.EXTRA_TEXT, "I'm being sent!!"); startActivity(Intent.createChooser(share, "Share Text")); return true; default: return super.onOptionsItemSelected(item); } }
and I have
setHasOptionsMenu(true);
in theonCreate()
. -
Edison Santos almost 11 yearsFor me, in order to intercept the menu click on the fragment, I had to return "false" on the onOptionsItemSelected of the FragmentActivity and on the onOptionsItemSelected of the fragment, do the desired behaviour.
-
nadeem gc over 10 yearsSame problem and it fixed for me too thanks. Can you tell why onOptionItemSelected didn't work ?
-
Youngjae over 10 years
return false
on Activity'sonOptionItemSelected
is the key. just replacereturn super.onOptionItemSelected(item);
-
Rajeev Sahu about 10 yearsWorking perfectly. Thanks Marco.
-
Chris Sprague almost 10 yearsGreat answer. You should change onCreateOptionsMenu(Menu menu) to onCreateOptionsMenu(Menu menu, MenuInflater inflater) when it's in a fragment
-
Darsh Patel almost 10 yearsIt's great solution. Thnakx Marco HC
-
user1634451 over 9 yearsCause the sherlock action bar doesn't use this method
-
slott over 9 yearsChange onMenuItemSelected to call onOptionItemSelected so your code will work when moving from ABS to appcompatlib
-
Han Tran over 9 yearsGreat solution my friend! Thankssss!
-
Moisés over 8 yearsfragment with setHasOptionsMenu(true); in onCreate and public boolean onOptionsItemSelected(MenuItem item) {} method did the magic
-
user3734429 over 8 years
setHasOptionsMenu(true)
is what I was looking for. Thanks -
Amru E. over 8 years@nadeemgc the reason it doesn't work is because Android knows about two types of menus: Options Menu and Context Menu. Actionbar Sherlock uses the Context Menu, which calls
onContextItemSelected
instead ofonOptionsItemSelected
. TheonMenuItemSelected
simply forwards the click to the correct method, which is why it appears to work better. -
nadeem gc over 8 years@AmruE. Thank you it will be helpful in future.
-
Roon13 over 8 years@Marco HC I am having this problem with fragments. I have 2 fragments in Navigation drawer. Both fragments have separate menu. But Even after switching, other fragment fragment menu shows previous fragment data
-
Roon13 over 8 years@Felixqk I am having problem like this with Fragments. I have two fragments. But fragment 2's OnOptionsSelectedItem is not getting called. Fragment 2 is showing fragment 1's menu option.
-
ahmadalibaloch about 8 years@Roon13 Remove the super.onCreateOptionsMenu; from fragment's onCreateOptionsMenu. + setHasOptionsMenu(true); worked for me without removing Activity onOptionsItemSelected.
-
Shailendra Madda over 6 yearsThe 3rd point
Inside your Activity's onOptionsItemSelected(MenuItem item) method, make sure you return false when the menu item action would be implemented in Fragment's onOptionsItemSelected(MenuItem item) method
helped a lot.. Thanks