Bottom Navigation view icon change not working

Viewed 1592

I want to change to icons of the bottom navigation view as we switch items.

enter image description here

I have light blue icons and dark blue icons for selected items. I am using selector drawable for each navigation item but I see the images like below in grey as inactive and blue as active

enter image description here

Here is my code

bottom_nav_menu

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

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/home_icon_selector"
        android:title="@string/title_home" />

    <item
        android:id="@+id/navigation_scheduler"
        android:icon="@drawable/schelduler_icon_selector"
        android:title="@string/title_scheduler" />

    <item
        android:id="@+id/navigation_favourites"
        android:icon="@drawable/favourites_icon_selector"
        android:title="@string/title_favourites" />


    <item
        android:id="@+id/navigation_settings"
        android:icon="@drawable/settings_icon_selector"
        android:title="@string/title_settings" />
</menu>

home

    <com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="@dimen/margin_20"
    android:layout_marginLeft="@dimen/margin_20"
    android:layout_marginRight="@dimen/margin_20"
    android:layout_marginEnd="@dimen/margin_20"
    android:layout_marginBottom="@dimen/margin_8"
    android:background="@drawable/bottom_navigation_background"
    android:elevation="8dp"
    app:itemIconTint="@drawable/bottom_navigation_color_selector"
    app:labelVisibilityMode="unlabeled"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:menu="@menu/bottom_nav_menu" />

And selectors

scheduler selector

    <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/qa_scheduler_inactive" android:state_checked="false"/>
    <item android:drawable="@drawable/ic_scheduler_blue" android:state_checked="true"/>
</selector>

Settings selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/qa_settings_inactive" android:state_checked="false"/>
    <item android:drawable="@drawable/ic_settings_blue" android:state_checked="true"/>
</selector>

Favorites selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/qa_favorites_inactive" android:state_checked="false"/>
    <item android:drawable="@drawable/ic_favourites_blue" android:state_checked="true"/>
</selector>

Home Selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/qa_home_inactive" android:state_checked="false"/>
    <item android:drawable="@drawable/ic_home" android:state_checked="true"/>
</selector>

Activity code

    val navView: BottomNavigationView = findViewById(R.id.nav_view)
    val navController = findNavController(R.id.nav_host_fragment)
    // Passing each menu ID as a set of Ids because each
    // menu should be considered as top level destinations.
    val appBarConfiguration = AppBarConfiguration(setOf(
            R.id.navigation_home, R.id.navigation_scheduler, R.id.navigation_favourites, R.id.navigation_settings))
    //  setupActionBarWithNavController(navController, appBarConfiguration)
    navView.setupWithNavController(navController)

What am I doing wrong here? Please help...

Edit : I am using following drawables

enter link description here

enter link description here

3 Answers

The reason of this issue is that there is always a value for app:itemIconTint, even if it is not used, it takes the default values of the primary/accent colors.

So to solve your problem you need to explicitly disable this with:

val btmNav = findViewById<BottomNavigationView>(R.id.nav_view)
navView.itemIconTintList = null

Although I do recommend another thing:

The icons are already the same icons in checked/unchecked states, but with different tint colors. If these icons are vectors, then you can just tint colors using a selector in app:itemIconTint, and use a single version of the icon without needing to duplicate the resources:

icon_color_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#2596CD" android:state_checked="true" />
    <item android:color="#84D0F4" android:state_checked="false" />
</selector>

And apply that:

<com.google.android.material.bottomnavigation.BottomNavigationView
    ...
    app:itemIconTint="@drawable/icon_color_selector"

And keep the menu items only with icons not the selectors, for instance:

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

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/home_icon"  //<<<<< icon not selector
        android:title="@string/title_home" />

    ....

</menu>

UPDATE:

As you are using navigation architecture components, make sure to have the same ids in the bottomNavView menu that matches the corresponding ones in the navGraph of the bottomNavView fragments.

In case you don't use a navGraph for the bottomNavView fragments, then you can't use navView.setupWithNavController(navController)

Here is with your drawable icon

This is just a wild guess, but maybe this line here:

app:itemIconTint="@drawable/bottom_navigation_color_selector"

is interfering with the colors of your drawables? If your drawables have the right colors (light blue/dark blue) they should work with your current selectors.

Alternatively, check that you don't set app:itemIconTint for the bottom-nav some other way, eg through a theme or programmatically!

You can achieve this using using selector like @Chris said or you can do it dynamically by using setOnNavigationItemSelectedListener{}

update - For changing icons , you can just brute force by changing the current item.icon to filled and others to unfilled icon , see here to get a gist of it (don't copy its for tabLayout).

navView.setOnNavigationItemSelectedListener { item -> 
            // change  the icon to filled icon
            true
        }

It seems so that listner is depreciated so refer this

Related