Hide options menu on PreferenceFragment

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

  • Android - onBackPressed() not working
  • What is the difference between total installs and active installs in the Android market?
  • NoSuchMethodError error for getActionBar() (API-8)
  • Package Manager in Android
  • Android as Dialup/FAX Modem
  • Implementing Google play and maps like Search Bar android
  • 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.

    Related posts:

    Android 6.0 Marshmallow. Cannot write to SD Card
    How to get input text from soft keyboard
    Accessing GoogleApiClient object in All Activities
    Get margin of a View
    Android: Getting Error: Conversion to Dalvik format failed
    Where are the drawables or clipart from android.R.drawable stored?
  • Difference among XML SAX parser, Pull parser & DOM Parser in android
  • HTML tags in string for TextView
  • Taking screenshot programmatically doesnt capture the contents of surfaceVIew
  • Delete file from internal storage
  • android: html in textview with link clickable
  • Android - multi-line linear layout
  • 2 Solutions collect form web for “Hide options menu on PreferenceFragment”

    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.

    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.
    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.