Search code examples
javaandroidandroid-fragmentsnavigation-drawerandroid-menu

Different action menu items for each fragment with same navigation drawer in Android


I have a Main activity that hosts a navigation drawer and multiple fragments. Each fragment has its own set of menu items.

Now the problem starts when I add the onOptionsItemSelected method, the navigation Drawer won't open. And when I don't add the onOptionsItemSelected method, navigation Drawer opens but then menu items are not working.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_payment_type_data_stats, parent, false);
    setHasOptionsMenu(true);
    return v;
}

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
    menu.clear();
    inflater.inflate(R.menu.menu_payment_type_stats, menu);
    Objects.requireNonNull(((MainActivity) Objects.requireNonNull(getActivity())).getSupportActionBar()).setTitle("title");
    super.onCreateOptionsMenu(menu, inflater);
}

@SuppressLint("NonConstantResourceId")
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_today:
            getDataForToday();
            break;
        case R.id.action_past_seven:
            getDataForPeriod(calendarDates.pastSeventhDate(), calendarDates.todayDate());
            break;
        case R.id.action_custom_date:
            openDatePickerDialog(sdf);
            break;
    }
    return true;
}

If you have any suggestions for fixing this problem, please share.


Solution

    • MainActivity changes:

    All you have to do is change onOptionsItemSelected in MainActivity from

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            return true;
        }
    

    and change it to

    @Override
        public boolean onOptionsItemSelected(MenuItem item) {
           return super.onOptionsItemSelected(item);  //important
        }
    

    As far as the onCreateOptionsMenu method in MainActivity, you can leave it empty with just

    return true
    
    • Fragment changes

    For fragment (each fragment can have separate action menu items) you need to implement 3 methods

    • onCreateView
    • onCreateOptionsMenu
    • onOptionsItemSelected

    Example:

    @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_payment_type_data_stats, parent, false);
            setHasOptionsMenu(true);  //important
            return v;
        }
    
        @Override
        public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
            menu.clear();
            //each frag can have different menu
            inflater.inflate(R.menu.menu_payment_type_stats, menu);
            super.onCreateOptionsMenu(menu, inflater);
        }
    
        @SuppressLint("NonConstantResourceId")
        @Override
        public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    
            switch (item.getItemId()) {
                case R.id.action_today:
                    getDataForToday();
                    break;
                case R.id.action_yesterday:
                    getDataForPeriod(calendarDates.yesterdayDate(), calendarDates.yesterdayDate());
                    break;
                case R.id.action_past_seven:
                    getDataForPeriod(calendarDates.pastSeventhDate(), calendarDates.todayDate());
                    break;
                case R.id.action_past_thirty:
                    getDataForPeriod(calendarDates.pastThirtiethDate(), calendarDates.todayDate());
                    break;
                case R.id.action_custom_date:
                    openDatePickerDialog(sdf);
                    break;
            }
            return false;
        }