(不赞成)片段onOptionsItemSelected没有被调用

编辑:这个问题是不赞成sherlock行动栏。 现在应该使用Android支持库

我添加了一个名为share的操作栏菜单选项,可以显示我的fragment ,但select事件不会被捕获

我像这样添加它

 @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); } 

试图在fragmentfragment activity捕获它

 @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); } } 

我有setHasOptionsMenu(true);onCreate()

同样的问题发生在我身上:

onMenuItemSelected事件没有在Fragment中调用

search谷歌无法find解决scheme,并在FragmentActivity中添加onMenuItemSelected方法不解决它。

最后通过参考http://developer.android.com/guide/topics/ui/actionbar.html来解决它;

注意:如果您通过片段类的onCreateOptionsMenucallback添加了片段中的菜单项,那么当用户select片段的其中一个项目时,系统将为该片段调用相应的onOptionsItemSelected()方法。 但是,活动首先有机会处理事件,因此系统在调用该片段的相同callback之前,先调用onOptionsItemSelected()。

这意味着只有在activity的onOptionsItemSelected()中没有该菜单项处理程序时,片段上的onOptionsItemSelected()才会被调用。

代码如下—–删除FragmentActivity上R.action.add的处理程序:

 @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); } } 

R.action.add在Fragment上的处理程序如下所示:

 @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); } } 

最后,请记住添加

  setHasOptionsMenu(true); 

在你的onCreate方法在Fragment中

我有同样的问题,但我认为总结和介绍最后一步才能正常工作更好:

  1. 在你的Fragment的onCreate(Bundle savedInstanceState)方法中添加setHasOptionsMenu(true) onCreate(Bundle savedInstanceState)方法。

  2. 在你的Fragment中覆盖onCreateOptionsMenu(Menu menu, MenuInflater inflater) (如果你想在Fragment的菜单中做一些不同的事情)和onOptionsItemSelected(MenuItem item)方法。

  3. 在Activity的onOptionsItemSelected(MenuItem item)方法中,确保在菜单项目动作将在Fragment的onOptionsItemSelected(MenuItem item)方法中实现时返回false

一个例子:

活动

 @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; } 

分段

 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; } 

我注意到人们给你的解决scheme是在活动中实现你的menue项目的代码,而不是片段。 我认为如果你在代码片段中实现了代码,而不是在我看来它更好看的活动中,它会看起来更加怪异。 为此,请执行以下操作:

活动

 @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; } 

分段

  @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; } 

现在行(和喜欢):“return super.onOptionsItemSelected(item);” 在活动和片段中是非常重要的,因为就像你将在debugging中跟随代码一样,你将会看到在活动中首先调用menue事件函数,并且如果该项目不匹配活动的switch-情况下,degault行:“super.onOptionsItemSelected(item);” 会根据需要调用片段上的onOptionsItemSelected函数。 (如果你有很多碎片,确保它们中有这个行,因为调用过程可能有些复杂)。

我正在使用actionbarsherlock。 这对我工作:

1)创builddummy_menu.xml菜单

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="fill_parent" > <item android:title="" android:showAsAction="never" android:id="@+id/dummyMenu" /> 

2)在活动中充气像这样的菜单:

 @Override public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu) { com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.dummy_menu,menu); return super.onCreateOptionsMenu(menu); } 

3)在片段onCreateView调用setHasOptionsMenu(true)并重写onCreateOptionsMenu和onOptionsItemSelected也像这样隐藏dummyMenu(在片段中)

  @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.fragment_actions, menu); MenuItem item = menu.findItem(R.id.dummyMenu); item.setVisible(false); super.onCreateOptionsMenu(menu, inflater); } 

希望它可以帮助别人。

编辑操作栏sherlock使用

我不得不使用

 public boolean onMenuItemSelected(int featureId, MenuItem item) { 

在捕获菜单项的主要活动中

它是如此简单,你可以在你的片段中做到这一点,以确保您的行动将正确听取:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } 

我有这个问题。 那是因为我错在了错误的方法

onOptionsItemSelected(com.actionbarsherlock.view.MenuItem项)是我用的。

确保你使用的是正确的!

你不是链接到活动方法中的超类。 请让onCreateOptionsMenu()返回super.onCreateOptionsMenu(menu),并让onOptionsItemSelected()返回super.onOptionsItemSelected(item)(除了正在处理的项目,应该返回true以表明您已经处理了该事件)