14

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

这是基本片段代码:

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

以及Activity中不断变化的片段代码:

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

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

4

5 回答 5

7

我知道我迟到了,但遇到了同样的问题——我的解决方案实际上是明确添加

setHasOptionsMenu(false);

到我的 SupportFragments onCreate 函数。这可以防止对活动的 onCreateOptionsMenu 和 onPrepareOptionsMenu 的任何额外调用。希望这可以帮助。

于 2014-06-13T13:45:06.927 回答
6

解决此问题的最简单方法是在菜单膨胀之前将其清除。

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

@Override
 public void   onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
      super.onCreateOptionsMenu(menu, inflater);
      menu.clear();
      inflater.inflate(R.menu.sample_menu, menu);
 }
于 2016-01-15T14:47:44.110 回答
3

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

1>尝试添加

设置保留实例(真);

分段构造函数!

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

这将在旋转时保存/恢复每个片段的各个状态

该问题似乎与Android在销毁活动时(旋转设备时)不会销毁片段有关。

我在 SO 的Jake Wharton在这里找到了这个

更新:2>另一种方法是避免在布局文件上添加片段,并且通过调用构造函数/newInstance方法手动实例化它们。

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

因此,请始终为您的片段添加 ID 和/或标签

3>通过调用 menu.clear() 试试这个

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

     }
于 2013-09-25T07:18:56.347 回答
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));
:

即检查菜单中是否存在您的菜单项之一,如果不存在,则可能需要添加所有菜单项。

于 2014-01-14T22:10:42.670 回答
0

使用menu?.clear()是一种解决方法。在使用之前,请确保您没有从MainActivity. 由于配置更改、应用程序长时间处于后台等原因,在重新创建应用程序时,活动和片段会自动重新创建。所以,从MainActivity我们不需要再创造MyFragment

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  if (savedInstanceState == null) { // This is what prevents recreating the fragment
    supportFragmentManager
      .beginTransaction()
      .add(R.id.fragment_container, MyFragment())
      .commit()
  }
}

如果您不检查,片段将在活动重新创建时再次添加。因此,工具栏将具有重复的菜单选项项。

于 2020-04-28T13:00:45.667 回答