2013-05-12 94 views
11

我有一个简单的应用程序与选项菜单,它在片段的开始处发生变化。 问题是,除了第一次onCreateOptionsMenu()调用两次 - onCreate()内和onResume()后,开始的任何片段。 在onCreate()我通过setHasOptionsMenu(true)将其称为manualy,但在onResume()之后它不应该发生。 此外,这只发生在第一个片段开始后。onCreateOptionsMenu()在片段中调用两次

这里是碱基片段代码:

class BaseFragment extends Fragment { 

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

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle clicks 
     return true; 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     // Create a menu 
     super.onCreateOptionsMenu(menu, inflater); 
    } 
} 

而在活动中的变化的代码片段:

public void startFragment(BaseFragment fragment) { 
    getSupportFragmentManager() 
    .beginTransaction() 
    .replace(android.R.id.content, fragment) 
    .commit(); 
} 

该示例不使用像ActionBarSherlock,仅SupportLibrary任何外部库。 我想,问题出在FragmentTransaction的replace()方法,因为它在第一个片段开始时工作正常。但我不知道,从哪里开始解决问题。我需要在View中完全替换片段。

+0

您正在使用哪款手机?如果手机有一个专门的菜单按钮,onCreateOptionsMenu将仅在用户点击该按钮时被调用。添加它不是强制性的,setHasOptionsMenu(true)应该调用onCreateOptionsMenu。它只是通知框架,当填充菜单时片段想要参与。 – prijupaul 2013-09-25 06:08:08

+0

当我遇到同样的问题时,OP甚至不会让我添加/编辑问题。我知道关于Menu的基本内容,这个问题与OP描述的一样很奇怪。 编辑:我使用嵌套片段 – Zyoo 2013-09-25 08:35:58

+0

@prijupaul它实际上只适用于前蜂窝版本。在调用setHasOptionsMenu()之后,在Honeycomb和稍后onCreateOptionsMenu将立即调用。 – bvitaliyg 2013-09-25 15:10:46

回答

-1

如果你不处理菜单项,你应该调用onOptionsItemSelected()的超类实现(默认实现返回false)。

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    return super.onOptionsItemSelected(item); 
} 
+0

为什么降低投票?它有什么错误。 – 2013-09-25 05:54:39

+0

我认为它的问题是使用onCreateOptionsMenu,而你的答案是使用onResume,它不适合onCreateOptionMenu和生命周期。 – prijupaul 2013-09-25 06:04:00

+0

没有。它不是手动调用的。当调用setHasOptionsMenu(true)时,它只是通知框架片段有菜单。适当时,框架会调用所需的功能。如果这没有设置为true,框架将不会调用片段中的oncreateoptionsmenu。 – prijupaul 2013-09-25 06:15:19

2

我想新添加的片段会导致活动onCreateOptionsMenu再次被调用!

1>尝试添加

setRetainInstance(真);

to fragment constructor!

public BaseFragment() 
{ 
    setRetainInstance(true); 
    setHasOptionsMenu(true); 
} 

,这会节省/旋转时恢复每个片的各个状态

这个问题似乎是相关的事实,当活动被销毁的Android不破坏片段(时设备旋转)。

我发现这个这里Jake Wharton在SO

更新: 2>另一种方式是避免增加对布局文件中的片段,并且还通过调用构造/ newInstance方法手动实例化它们。

如果你在布局上添加一个片段,android框架会为你实例化它。 而不是手动实例化片段,您应该通过调用FragmentManager.getFragmentById来检索它的实例,并改为使用该实例。

所以始终包含您的片段

3>试着用这个ID和/或标签通过调用menu.clear()

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

    } 
+1

不,我不认为这是答案。当然,我尝试了上面所说的所有内容,但每当我测试它时它都会发生 – Zyoo 2013-09-25 08:33:20

+0

@Zyoo为您的问题提供了其他解决方案吗? – 2013-11-20 06:27:41

+0

对不起,我决定不使用optionmenu,但我认为将来它会被需要,所以我仍然试图 – Zyoo 2013-11-20 14:51:13

0

也许你可以尝试这样的:

private final int MENU_SEARCH=Menu.FIRST; 
: 
    @Override public void onPrepareOptionsMenu(Menu menu) { 
     if (menu.findItem(MENU_SEARCH)==null) { 
      menu.add(0, MENU_SEARCH, Menu.NONE, getText(R.string.menu_search)); 
: 

iee检查菜单中是否存在其中一个菜单项,如果不存在,则可能需要添加所有菜单项。

7

我知道我迟到了,但遇到同样发出─和我的解决方案实际上是明确添加

setHasOptionsMenu(false); 

我SupportFragments的onCreate功能。这可以防止对活动onCreateOptionsMenu和onPrepareOptionsMenu的额外调用。希望这可以帮助。

2

解决问题的最简单方法是在充气之前清除菜单。

menu.clear()将清除任何现有的菜单,并开始一个新的菜单。

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