在PreferenceFragment中隐藏选项菜单

9

我有一个包含多个片段的应用。

只有 A 片段拥有选项菜单。 B 片段可以从扩展列表片段的 B 片段中初始化。

因此,如果我从 B 片段中选择某个项目,则会启动带有选项菜单的 A 片段。如果返回,B 片段仍然没有选项菜单。

问题在于,如果我的当前窗口是 A 片段,而我从导航抽屉中选择“设置”菜单(扩展了首选项片段),则会显示带有来自 A 片段的选项菜单的设置片段。但如果我从导航抽屉中选择“设置”菜单,而我的当前窗口是 B、C、D(没有选项菜单),则一切都正常。

片段 A:

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

    inflater.inflate(R.menu.menu_station, menu);
}

设置碎片:

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

    setHasOptionsMenu(true);

    sharedPreferenceSettings = new SharedPreferenceSettings(getActivity());

    addPreferencesFromResource(R.xml.settings);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_settings, container, false);
}

问题出在哪里?

编辑:

经过数小时的调试,我找到了解决方案。问题在于不同的碎片事务使用了不同的fragmentManager。对于设置碎片,我只使用了getSupportFragmentManager(),而对于其他碎片则使用了fragmentManager()。这导致一些碎片无法移动到后台堆栈。


我不理解你的第四段,抱歉。在片段和两个菜单之间跟随逻辑流程很困难。如果您想更清晰地表达,请建议将代码/逻辑流程分开,一行一个流程。另外,可以绘制流程图来说明。 - The Original Android
2个回答

7

我看到了两个代码嫌疑人。 对于A片段的代码建议:

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

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

注意事项:

  • super.onCreateOptionsMenu()通常在inflate之后调用。这一点没有很好的文档说明,因此我不确定区别是什么。相关的SO帖子中有很多人认为最佳答案,链接如下:Android Options Menu in Fragment
  • setHasOptionsMenu(true)在同一个fragment中完成,而不是在Settings fragment中。Fragments保存自己的数据和状态。你不能很容易地在不同的fragments之间修改状态。

3

根据您的帖子,我认为您应该使用一个临时 fragment 布局来替换所需的 fragment。

代码建议:

FragmentManager fragManager = this.getSupportFragmentManager();

MyFragment myFragment = MyFragment.newInstance();
FragmentTransaction fragmentTransaction = fragManager.beginTransaction();

FragmentTransaction transaction = this.getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.sample_content_fragment, myFragment, "MyFrag");
transaction.addToBackStack(null);       // support the Back key
transaction.commit();

在布局中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/sample_main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
...
    <FrameLayout
          android:id="@+id/sample_content_fragment"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
        />
...
</LinearLayout>

注意事项:

  • 临时片段布局被称为sample_content_fragment。这是维护一个片段堆栈的父容器。
  • 这种技术只使用一个片段堆栈来管理,而不是多个堆栈。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接