Selected tab's color in Bottom Navigation View

I'm adding a BottomNavigationView to a project, and I would like to have a different text (and icon tint) color for the selected tab (to achieve greying out non-selected tabs effect). Using a different color with android:state_selected="true" in a color selector resource file doesn't seem to work. I also tried having additional item entries with android:state_focused="true" or android:state_enabled="true", no effect unfortunately. Also tried setting the state_selected attribute to false (explicitly) for the default (non-selected) color, with no luck.

Here is how I add the view to my layout:

<android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:itemBackground="@color/silver"
        app:itemIconTint="@color/bnv_tab_item_foreground"
        app:itemTextColor="@color/bnv_tab_item_foreground"
        app:menu="@menu/bottom_nav_bar_menu" />

Here is my color selector (bnv_tab_item_foreground.xml):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/darker_gray"  />
    <item android:state_selected="true" android:color="@android:color/holo_blue_dark" />
</selector>

And my menu resource (bottom_nav_bar_menu.xml):

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

    <item
        android:id="@+id/action_home"
        android:icon="@drawable/ic_local_taxi_black_24dp"
        android:title="@string/home" />
    <item
        android:id="@+id/action_rides"
        android:icon="@drawable/ic_local_airport_black_24dp"
        android:title="@string/rides"/>
    <item
        android:id="@+id/action_cafes"
        android:icon="@drawable/ic_local_cafe_black_24dp"
        android:title="@string/cafes"/>
    <item
        android:id="@+id/action_hotels"
        android:icon="@drawable/ic_local_hotel_black_24dp"
        android:title="@string/hotels"/>

</menu>

I would appreciate any help.


While making a selector, always keep the default state at the end, otherwise only default state would be used. You need to reorder the items in your selector as:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="@android:color/holo_blue_dark" />
    <item android:color="@android:color/darker_gray"  />
</selector>

And the state to be used with BottomNavigationBar is state_checked not state_selected.


1. Inside res create folder with name color (like drawable)

2. Right click on color folder. Select new-> color resource file-> create color.xml file (bnv_tab_item_foreground) (Figure 1: File Structure)

3. Copy and paste bnv_tab_item_foreground

<android.support.design.widget.BottomNavigationView
            android:id="@+id/navigation"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="0dp"
            android:layout_marginStart="0dp"
            app:itemBackground="@color/appcolor"//diffrent color
            app:itemIconTint="@color/bnv_tab_item_foreground" //inside folder 2 diff colors
            app:itemTextColor="@color/bnv_tab_item_foreground"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:menu="@menu/navigation" />

bnv_tab_item_foreground:

 <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_checked="true" android:color="@color/white" />
        <item android:color="@android:color/darker_gray"  />
    </selector>

Figure 1: File Structure:

Figure 1: File Structure


BottomNavigationView uses colorPrimary from the theme applied for the selected tab and it uses android:textColorSecondary for the inactive tab icon tint.

So you can create a style with the prefered primary color and set it as a theme to your BottomNavigationView in an xml layout file.

styles.xml:

 <style name="BottomNavigationTheme" parent="Theme.AppCompat.Light">
        <item name="colorPrimary">@color/active_tab_color</item>
        <item name="android:textColorSecondary">@color/inactive_tab_color</item>
 </style>

your_layout.xml:

<android.support.design.widget.BottomNavigationView
            android:id="@+id/navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/windowBackground"
            android:theme="@style/BottomNavigationTheme"
            app:menu="@menu/navigation" />

If you want to change icon and text colors programmatically:

ColorStateList iconColorStates = new ColorStateList(
     new int[][]{
          new int[]{-android.R.attr.state_checked},
          new int[]{android.R.attr.state_checked}
     },
     new int[]{
          Color.parseColor("#123456"),
          Color.parseColor("#654321")
     });

navigation.setItemIconTintList(iconColorStates);
navigation.setItemTextColor(iconColorStates);