MenuItem doesn’t appear in toolbar

Tags: , , ,



I’m facing a problem. I can’t make a toolbar to show me a menu. I know that this question was asked here previously here, and I went through all possible solutions, but none of them gave me desired result. So I’m using 1 activity and few fragments and I want to show different menu items in a toolbar according to fragment. Here is my MainActivity.java

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{

    DrawerLayout drawerLayout;
    NavigationView drawerView;
    NavController navController;
    AppBarConfiguration appBarConfiguration;
    ConstraintLayout container;
    Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        drawerLayout = findViewById(R.id.drawer_layout);
        drawerView = findViewById(R.id.drawer_view);
        toolbar = findViewById(R.id.toolbar);
        BottomNavigationView navView = findViewById(R.id.nav_view);
        container = findViewById(R.id.container);

        drawerView.bringToFront();
        NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
                .findFragmentById(R.id.nav_host_fragment);

        navController = navHostFragment.getNavController();
        //NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        appBarConfiguration = new AppBarConfiguration.Builder(R.id.navigation_main, R.id.navigation_favourite,
                R.id.navigation_add_announce,R.id.navigation_notifications,
                R.id.navigation_profile).setOpenableLayout(drawerLayout).build();

        NavigationUI.setupWithNavController(drawerView, navController);
        NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);
        NavigationUI.setupWithNavController(navView, navController);
        drawerView.setCheckedItem(R.id.drawer_main);
        drawerView.setNavigationItemSelectedListener(this);
        animateDrawer();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.profile_fragment_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.onNavDestinationSelected(item, navController)
                || super.onOptionsItemSelected(item);
    }


And i want to show LogIn text in ProfileFragment toolbar ProfileFragment.java code:

import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;

import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;


public class ProfileFragment extends Fragment {

    ProfileViewModel mViewModel;

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

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        mViewModel = new ViewModelProvider(this).get(ProfileViewModel.class);
        View root = inflater.inflate(R.layout.profile_fragment, container, false);



        return root;
    }

    public void onCreateOptionsMenu (Menu menu, MenuInflater inflater){
        inflater.inflate(R.menu.profile_fragment_menu, menu);
    }


}

profile_fragment_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/registerFragment"
        android:title="@string/enter_acc"<!-- LogIn -->
        app:showAsAction="always"/>

</menu>

mobile_navigation.xml holds navigation graph

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mobile_navigation"
    app:startDestination="@+id/navigation_main">

    <fragment
        android:id="@+id/navigation_main"
        android:name=".ui.main.MainFragment"
        android:label="@string/nav_bar_main"
        tools:layout="@layout/main_fragment" />

    <fragment
        android:id="@+id/navigation_favourite"
        android:name=".ui.favourite.FavouriteFragment"
        android:label="@string/nav_bar_favourite"
        tools:layout="@layout/favourite_fragment" />

    <fragment
        android:id="@+id/navigation_add_announce"
        android:name=".ui.add.AddFragment"
        android:label="@string/nav_bar_add_announce"
        tools:layout="@layout/add_fragment" />

    <fragment
        android:id="@+id/navigation_notifications"
        android:name=".ui.notifications.NotificationsFragment"
        android:label="@string/nav_bar_notifications"
        tools:layout="@layout/notifications_fragment" />

    <fragment
        android:id="@+id/navigation_profile"
        android:name=".ui.profile.ProfileFragment"
        android:label="@string/nav_bar_profile"
        tools:layout="@layout/profile_fragment" >
        <action
            android:id="@+id/action_navigation_profile_to_registerFragment"
            app:destination="@id/registerFragment" />
    </fragment>
    <fragment
        android:id="@+id/registerFragment"
        android:name=".ui.profile.register.RegisterFragment"
        android:label="register_fragment"
        tools:layout="@layout/register_fragment" />
</navigation>

I tried toolbar.inflateMenu(R.menu.profile_fragment_menu) in MainActivity within onCreate method and menu item appeared and was clickable but it was showing on all fragments + onOptionsItemSelected didn’t process click on item. My last try you can see in my code. Thank you in advance

Answer

If you want to use the Toolbar as ActionBar and use the ActionBar API (as onCreateOptionsMenu) you have to add setSupportActionBar(toolbar);

   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

Otherwise if you don’t call setSupportActionBar you can use the Toolbar APIs directly and use the method inflateMenu() in each fragment. Something like:

toolbar.inflateMenu(R.menu.xxxxx)

and then use the setOnMenuItemClickListener method to set a clickListener.



Source: stackoverflow