Search code examples
androidandroid-fragmentsmenuitem

How do i attach fragments using on options item selected using menu items


Hello am having a menu layout that has a menu item. The menu item has an item with action view class which is supposed to attach a fragment on click. How do i get to attach the AccountManagementFragment when use clicks on the action_account menu item using action view class of the menu item

My menu item layout


<item android:id="@+id/action_account"
        android:title="Account"
        android:icon="@drawable/ic_profile"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="ke.co.clinton.hama.viewslogic.account.AccountManagementFragment"/>

My onCreateOptionsMenu and onOptionsItemsSelected methods


@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        if (item.getItemId() == R.id.search) {

        }

        return super.onOptionsItemSelected(item);

    }

My fragment class


import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import ke.co.clinton.hama.MainActivity;
import ke.co.clinton.hama.R;
import ke.co.clinton.hama.interfaces.DrawerLocker;

public class AccountManagementFragment extends Fragment {

    private AccountManagementViewModel mViewModel;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        ((MainActivity)getActivity()).getSupportActionBar().hide();
        ((DrawerLocker) getActivity()).setDrawerEnabled(false);
        View view = inflater.inflate(R.layout.fragment_account_management, container, false);
        Toolbar toolbar = view.findViewById(R.id.toolbar);
        toolbar.setTitle("Title");
        toolbar.setNavigationIcon(R.drawable.ic_back_button);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().onBackPressed();
            }
        });
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mViewModel = ViewModelProviders.of(this).get(AccountManagementViewModel.class);
        // TODO: Use the ViewModel

    }


    @Override
    public void onResume() {
        super.onResume();
        ((MainActivity)getActivity()).getSupportActionBar().hide();
        ((DrawerLocker) getActivity()).setDrawerEnabled(true);
    }
    @Override
    public void onStop() {
        super.onStop();
        ((MainActivity)getActivity()).getSupportActionBar().show();
        ((DrawerLocker) getActivity()).setDrawerEnabled(true);
    }

}


Solution

  • You cannot pass Fragment as app:actionViewClass in menu items. What you can really do is attach the fragment when the menu item is selected inside onOptionItemSelected.

    1. Remove the app:actionViewClass from menu item

      <item android:id="@+id/action_account"
          android:title="Account"
          android:icon="@drawable/ic_profile"
          app:showAsAction="collapseActionView|ifRoom"/>
      
    2. Add a static method inside AccountManagementFragment to get the instance

      public class AccountManagementFragment extends Fragment {
          ...
          ...
      
          static AccountManagementFragment newInstance() {
              return AccountManagementFragment();
          }
          ...
          ...
      }
      
    3. Change the implementation of onOptionsItemSelected to add the fragment

      @Override
      public boolean onOptionsItemSelected(@NonNull MenuItem item) {
      
          if (item.getItemId() == R.id.action_account) {
              // Make sure to add a fragment container view in the layout (preferably a FrameLayout)
              // Here I am assuming the id is 'container'
              getSupportFragmentManager().beginTransaction()
                  .replace(R.id.container, AccountManagementFragment.newInstance())
                  .commit()
          }
      
          return super.onOptionsItemSelected(item);
      }