42

I want to hide a menu item of BottomNavigationView dynamically based on some conditions. I tried the following but it is not working.

mBottomNavigationView.getMenu()
            .findItem(R.id.item_name)
            .setVisible(false);

mBottomNavigationView.invalidate();
Ram
  • 1,474
  • 1
  • 10
  • 17

9 Answers9

88
mBottomNavigationView.getMenu().removeItem(R.id.item_name);

removeItem does the trick. Not sure why setVisible method is not working.

Ram
  • 1,474
  • 1
  • 10
  • 17
  • 1
    Glad you found a solution. I deleted my answer as not helpful, voted yours up. Could it be that setVisibility is not a method of the BottomNavigationView or any of its inherited methods, whereas it does use a menu resource file so can use the public methods of menu which includes removeItem?https://developer.android.com/reference/android/support/design/widget/BottomNavigationView.html – Lew Perren Jul 12 '17 at 09:18
  • Is there any method to set it visible dynamically – Jinson Paul Feb 05 '18 at 05:14
  • 1
    @JinsonPaul I think add() method will work since removeItem works for removing. But it would be great if someone could explain why setVisible() method is not working. – Ram Feb 05 '18 at 10:37
  • 2
    This works for me but if I have anything less than 5 menu items the bottom navigation items are not evenly spaced. I think this may have something to do with "shift mode"? In a perfect world the navigation would evenly distribute any number of menu items... – Dan Jun 01 '18 at 17:14
  • 1
    Hi @Dan i too had same issue where when i removed an item it doesnt evenly distribute the rest of the items – Jono Feb 10 '20 at 10:26
  • Anyone thinking about why not choose, setVisibility(View.GONE), over this solution, here is the reason: 'setVisibility()' only hides the view and as soon as you tap on another menu item, the hidden one is visible again and probably you'd have to do more work. Also, the menu items does not get distributed equally over the width. But if you remove it, both these issues do not occur and hence seems like the best solution. – Mayank Sehgal Feb 24 '20 at 09:54
17

You can hide a menu item by setting isVisible as false with using suggested property isVisible in Kotlin. But this makes your menu item removed from BottomNavigationView on Android 9 as my observation.

bottomNavigation.menu.findItem(R.id.menu_item).isVisible = false

If you use a single color for your bottom navigation view's background you can use similar approach to save the menu items in place. As an example the one in the right edge.

// 0x000000 is black as an example
bottomNavigation.menu.findItem(R.id.menu_item).icon = ColorDrawable(0x000000)
// and disable for the actions
bottomNavigation.menu.findItem(R.id.menu_item).isEnabled = false
abdullahselek
  • 7,893
  • 3
  • 50
  • 40
13

Try this:

navView.getMenu().findItem(R.id.your_menu_item_id).setVisible(true);
navView.getMenu().findItem(R.id.your_menu_item_id).setVisible(false);
m02ph3u5
  • 3,022
  • 7
  • 38
  • 51
Mahtab
  • 269
  • 3
  • 11
9

I tried most of solutions but this worked for me,

For hiding an item dynamically : bottomNavigationView.findViewById(R.id.xyz).setVisibility(View.GONE);

For making item visible: bottomNavigationView.findViewById(R.id.xyz).setVisibility(View.VISIBLE);

  • For me `.setVisibility()` gives an unresolved reference. – Dan Jun 01 '18 at 17:11
  • 1
    This worked perfect for me - I need to show and hide an item depending on a user condition and this is easier than remove and add. – 19Craig Aug 06 '18 at 23:13
7

setVisibility should work for you. FYI, below example is in kotlin.

bottomNavigationView.menu.findItem(R.id.navigation_item_two).isVisible = false
soshial
  • 5,906
  • 6
  • 32
  • 40
Sahitya Pasnoor
  • 597
  • 5
  • 11
3

The removeItem displaces the menu items in the bar when an item(s) is hidden. I found a slightly better way. Create a group of menu items that you would want to hide your menu xml.

In your bottom_menu.xml

<menu...>
    <group android:id="@+id/hiddenmenu">
        <item.../>
        <item.../>
    </group>
    <item.../>
</menu>

And in your activity.cs

Menu menu = mbottomNavigation.getMenu();  
menu.setGroupEnabled(R.id.hiddenmenu, false);

Although, with this setup, when all menu items are visible, the checked change state of the menu items goes out of whack. Also tried programmatically adding menu items to an empty group but the group stopped responding to the GroupDisable...

Gk Mohammad Emon
  • 6,084
  • 3
  • 42
  • 42
Bilal Kazi
  • 126
  • 1
  • 11
3

In Kotlin you can use this line of code:

 mainActivitbinding.bottomNav.menu.removeItem(R.id.watch_list_tab)
Osama Ibrahim
  • 995
  • 10
  • 13
1

It works for me in kotlin like this:

bottomNavigationView.rootView.findViewById<View>(R.id.nav_nearestRestaurant).visibility = View.GONE

But the thing is that if you click in another item, the hidden item appears again, because the bottom bar reload its appearance when show you the active item (so if in your xml menu, its visible, appears visible again (I think, to me happen like that))

0

In my case, I wanted to hide the toolbar text and the icons/titles of BottomNavigationView items in the authorization fragment, which handles the initial loading of my application. When it determines that the user is authenticated and fetches their profile from the database, I load the feed fragment, which fetches data from the database and displays it to the user. What I did was add the following method to the activity that creates the layout elements and call it from its fragments, passing in a boolean to determine visibility of the items.

public void setBottomNavigationViewItemsVisibility(boolean value) {
    if (this.bottomNavigationView != null) {
        this.bottomNavigationView.setVisibility(View.VISIBLE);
        Menu menu = this.bottomNavigationView.getMenu();
        if (value) {
            int[] icons = {R.drawable.ic_event_white_24dp, R.drawable.ic_explore,
                    R.drawable.ic_store_white_24dp, R.drawable.ic_notifications_white_24dp};
            int[] titles = {R.string.feed, R.string.explore, R.string.finder, R.string.notifications};
            for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setIcon(icons[i]);
                menu.getItem(i).setTitle(titles[i]);
                menu.getItem(i).setEnabled(true);
            }
        } else {
            for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setIcon(R.drawable.ic_empty);
                menu.getItem(i).setTitle(R.string.title_empty);
                menu.getItem(i).setEnabled(false);
            }
        }
    }
}

We declare an array of drawable ids and an array of title ids to match what we have declared in the menu XML file. If true, we iterate through the menu items and set their icon, title, and their state to default values. If false, we set the icon to a transparent icon (removing the icon affects its size), set the toolbar title to an empty string, and disable it.

BottomNavigationView Menu:

<?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"
    android:id="@+id/bottom_navigation_view_home">

    <item
        android:id="@+id/action_feed"
        android:enabled="true"
        android:icon="@drawable/ic_event_white_24dp"
        android:title="@string/feed"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_explore"
        android:enabled="true"
        android:icon="@drawable/ic_explore"
        android:title="@string/explore"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_finder"
        android:enabled="true"
        android:icon="@drawable/ic_store_white_24dp"
        android:title="@string/finder"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_notifications"
        android:enabled="true"
        android:icon="@drawable/ic_notifications_white_24dp"
        android:title="@string/notifications"
        app:showAsAction="ifRoom" />
</menu>

Empty Icon (ic_empty.xml):

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <path
        android:fillColor="#00FFFFFF"
        android:pathData="M8" />
</vector>

Empty Title (title_empty):

<string name="title_empty" />