片段不接收菜单callback

我有一个片段类,它扩展了Fragment并调用setHasOptionsMenu参与菜单。 这个类还实现了onCreateOptionsMenuonPrepareOptionsMenuonOptionsItemSelected

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

我dynamic加载这个片段使用FragmentTransaction在我的活动(扩展FragmentActivity )。

然而没有菜单callback( onCreateOptionsMenuonPrepareOptionsMenuonOptionsItemSelected )被调用(我debugging了这些方法中的一些断点),菜单不显示。

我错过了什么吗? 我需要在我的活动中添加一些内容吗?

我正在使用Android兼容性库,使用L11 SDK编译并在Xoom中进行testing。

编辑 :我发现了这个问题。 我的AndroidManifest是针对L11,这似乎隐藏菜单button,并阻止被调用的callback。 但是,如果我从清单中删除了这个,我就会丢失一些我需要的其他function(例如列表中的激活状态)。 有谁知道如何解决这个问题(启用菜单button),而无需从清单中删除targetSdkVersion=11

Aromero,不要忘记使用方法的片段版本来覆盖onCreateOptionsMenu,类似如下:

  @Override public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.queue_options, menu); super.onCreateOptionsMenu(menu, inflater); } 

顺便说一下,这将在片段中进行,并添加到Activity的充气菜单中(如果有的话)。 自己也有同样的问题,直到我明白了这一点。

如果你遇到了ActionBarSherlock的这个问题,你需要确保你的碎片是SherlockFragments,而不仅仅是SupportFragments,而你正在重写的是

 public void onPrepareOptionsMenu (com.actionbarsherlock.view.Menu menu) { 

 public void onPrepareOptionsMenu (android.view.Menu menu) { 

如果你做了后者,你应该得到一些有关函数是最终的警告,你无法覆盖它。 这是一个警告,你正试图重写错误的function!

如果通过将类从SherlockFragment切换到仅仅片段来修复错误,则可以创build该函数。 。 。 但它不会被调用。

我有同样的问题,但我认为最好总结和介绍最后一步,使其工作:

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

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

  3. onOptionsItemSelected(MenuItem item) Activity的方法中,确保在onOptionsItemSelected(MenuItem item) Fragment的方法中实现菜单项目操作时返回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) { // 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; } 

我希望这会有所帮助。

干杯。

如果你有一个活动和一个片段,每个都加载菜单项,那么你需要特别注意你使用的覆盖。

活动可以覆盖onOptionsItemSelectedonMenuItemSelected ,但片段只能覆盖onOptionsItemSelected

如果您在您的活动中覆盖onMenuItemSelected并在您的片段中覆盖onOptionsItemSelected ,则您的片段覆盖将永远不会被触发。

而是在activity和fragment中使用onOptionsItemSelected

你需要确保你调用setHasOptionsMenu(true); 在片段中调用onCreateonCreateView

您还需要在片段中实现onCreateOptionsMenu的覆盖。

另一种可能的情况是,当你在每个片段中使用一个公共的动作时, 例如R.id.action_add

今天我有这样的情况:点击选项菜单[add]被调用了“错误” onOptionItemSelected因为每个片段(使用DrawerLayoutdynamicreplace)具有相同的R.id.action_add

简短的故事,如果你有这样的情况总是检查你的片段是可见的:

if (!isVisible()) return false;

onOptionItemSelected ,关注onOptionItemSelected链!

  MainActivity | | onOptionItemSelected +----------------------- | return false | MyCoolFragment1 | | onOptionItemSelected +----------------------- | return false | MyCoolFragment2 | | onOptionItemSelected +----------------------- | return true | [item selection handled] 

如果你添加你的片段(如下所示):

 getSupportFragmentManager() .beginTransaction() .replace(R.id.content_frame, MyCoolFragment1.newInstance()) .commit() 

并且你已经为每个片段中的一个普通的动作(比如R.id.action_add)定义了相同的ID; 不要忘记添加这一行到每个:if(!isVisible())返回false;

 @Override public boolean onOptionsItemSelected(MenuItem item) { if (!isVisible()) return false; // <-- Not visible? skip! if (item.getItemId() == R.id.action_add) { //.TODO whatever return true; //.Handled! } return false; //.Skip } 

当我将ViewPagerIndicator与ActionBarSherlock结合使用时遇到了这个问题。 虽然看起来这是固定的,但我仍然遇到了这个问题。 我发现的工作是手动调用片段。

 @Override public boolean onOptionsItemSelected(MenuItem item) { Toast.makeText(this, "From activity", Toast.LENGTH_SHORT).show(); // TODO Fragment currentFragment = mAdapter.getItem(mPager.getCurrentItem()); if (currentFragment != null && currentFragment instanceof SherlockFragment) { ((SherlockFragment)currentFragment).onOptionsItemSelected(item); } return super.onOptionsItemSelected(item); } 

我发现了这个问题。 AndroidManifest是针对SDK 11,这似乎隐藏菜单button,并阻止被调用的callback。 我认为这打破了似乎被Android 3.0中的操作栏所取代的菜单button的兼容性

我认为你已经实现了onCreateOptionsMenuonPrepareOptionsMenuonOptionsItemSelectedextends Fragment的类中。 在你正在加载这个片段的Activity类中这样做

从android开发人员网站 – 链接

注意:如果通过Fragment类的onCreateOptionsMenu()callback从片段中充填菜单项,则当用户select其中一个项目时,系统将调用onOptionsItemSelected()。 但是,活动首先有机会处理事件,因此系统首先在活动上调用onOptionsItemSelected(),然后调用该片段的相同callback 。 为了确保活动中的任何片段也有机会处理callback,总是将调用作为默认行为传递给超类,而不是在不处理该项时返回false

所以Marco HC是最好的答案。

我有同样的问题和解决scheme,为我工作是:

  1. 删除或注释任何onOptionsItemSelected(),onMenuItemSelected(),甚至onPrepareOptionMenu(),并保留在Activity onCreateOptionsMenu()中:

     @Override public boolean onCreateOptionsMenu(Menu menu){ MenuInflater inflater=getMenuInflater(); inflater.inflate(R.layout.menu, menu); return true; } 
  2. 在片段类中,在onCreateView()中,把:

     setHasOptionsMenu(true); 
  3. 在片段类中添加:

     @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu,inflater); } @Override public boolean onOptionsItemSelected(MenuItem item){ switch(item.getItemId()){ case R.id.action_insert: //doing stuff return true; } return false; } 

经过testing,并在Android 4.4上工作

如果您的工具栏在父活动xml中定义,请确保在您的片段中执行此操作

 @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { .... Toolbar toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar); ((AppCompatActivity)getActivity()).setSupportActionBar(toolbar); setHasOptionsMenu(true); } 

然后,当然,像下面覆盖onCreateOptionsMenu

 @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.edit_menu, menu); super.onCreateOptionsMenu(menu, inflater); } 

这是为我工作的唯一解决scheme!