9

I have an app with several fragments.

Only A fragment has an options menu. A fragment could be initiated from fragment B (which extends listfragment).

So B fragment does not have an options menu, if I select some item from it, fragment A will be initiated with an options menu and if go back, fragment B still does not have an options menu.

The problem is if I select Settings menu (which extends preferencefragment) from navigation drawer while my current window is fragment A, a settings fragment will be shown with options menu from fragment A. But if I select Settings menu from navigation drawer while my current window is fragment B, C, D (without options menu) everything works well.

Fragment A:

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

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

Settings fragment:

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

Where is the problem?

EDIT:

After hours of debugging I found a solution. The problem was different fragmentManager for fragments transaction. For settings fragment only I used getSupportFragmentManager(), for others - fragmentManager(). This causes some fragments from moving to back stack.

burjulius
  • 279
  • 3
  • 17
  • I don't understand your fourth paragraph, sorry. It is hard to follow the logic flow between fragments and two menus. If you want to be clearer, I suggest separating the code/logic flow, one flow on one line. Another, is draw a diagram of the flow. – The Original Android Aug 12 '15 at 08:00

2 Answers2

7

I see two code suspects. Code suggestion for Fragment 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);
...
}

Notes:

  • super.onCreateOptionsMenu() is normally called after inflate. This is not well documented so I am not sure what the difference is. A related SO post that many agrees as the best answer is @ Android Options Menu in Fragment.
  • setHasOptionsMenu(true) is done in the same fragment instead of Settings fragment. Fragments save its own data and states. You cannot modify states between fragments so easily.
Community
  • 1
  • 1
The Original Android
  • 6,147
  • 3
  • 26
  • 31
3

From reading your post, I think you should use a temporary fragment layout to be replaced by the desired fragment. Code suggestion:

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

In the Layout:

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

Notes:

  • The temporary fragment layout is called sample_content_fragment. This is the parent container to maintain one fragment stack.
  • This technique uses only one fragment stack to manage instead of several stacks.
The Original Android
  • 6,147
  • 3
  • 26
  • 31