16

I have a Fragment with menu:

public class FragmentA extends Fragment {

    public FragmentA() {
        setHasOptionsMenu(true);
    }

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

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

I would like to change menu but it doesn't work and keep the old action menu

Fragment B is equals like above with different inflate XML menu.

public class FragmentB extends Fragment {

    public FragmentB() {
        setHasOptionsMenu(true);
    }

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

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

EDITED:

Can be useful to use different menu layout for different fragments and 1 menu layout for main activity and differents id

ALXKAY
  • 21
  • 1
  • 7
alfo888_ibg
  • 1,847
  • 5
  • 25
  • 43

3 Answers3

37

Put setHasOptionsMenu(true) in constructor and inflate fragment specific menu.

public class FragmentA extends Fragment {

    public FragmentA() {
       setHasOptionsMenu(true);
    }

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

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

menu in main activity

public class MainActivity extends Activity {
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.main_menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
}
Boban S.
  • 1,662
  • 13
  • 16
  • inflate the menu you want, main menu needs to be inflated in main activity and menu specific for fragments needs to be inflated in fragments. – Boban S. Apr 28 '14 at 11:08
  • 1
    thanks it works, I'm using different menu layout btw – alfo888_ibg Apr 29 '14 at 09:40
  • 15
    Mine worked after I added the line menu.clear(); to the fragment's onCreateOptionsMenu code. – Alan Nelson Apr 03 '17 at 03:05
  • Note that it is not necessary to call `setHasOptionsMenu(true)` also in the constructor. See https://stackoverflow.com/a/34597423/905686. – user905686 Jan 12 '18 at 16:20
  • just to note, `onCreateOptionsMenu()` in a Fragment has a 2nd param, the `MenuInflater`, so if you're trying to copy/paste the function from an Activity, you will get an error. – lasec0203 Sep 23 '19 at 04:47
4

Can all be done via Fragment - no need to inflate menu from activity:

public class UpdateFragment extends Fragment  {

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

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

        inflater.inflate(R.menu.update_menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id){
            case R.id.navUpdateProfile:
                showToast("navUpdateProfile");
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }
}
Gene Bo
  • 11,284
  • 8
  • 90
  • 137
0

If you have several fragments that share the same menu with some exceptions.

  class BaseFragment:Fragment(){
    
    open var menuId = R.menu.default_menu
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setHasOptionsMenu(true) // will apply to all children
        }
        override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
            super.onCreateOptionsMenu(menu, inflater)
            inflater.inflate(menuId, menu) // will apply to all children except for overridden
        }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
            // all menu ids can be listed here unless specific to code in child
            when (item.itemId) {
                R.id.menu_option_1 -> {
                      // do something
                }
                R.id.menu_option_2 -> {
                    //do something
            }
            return false
        }
    }
    
    class ChildFragment:BasFragment(){
    
 override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            menuId = R.menu.menu_2 // change to a different menu as desired here
        }
    }
Hesham Fas
  • 876
  • 1
  • 9
  • 20