Selected tab's color in Bottom Navigation View

AndroidMaterial DesignNavigationbar

Android Problem Overview


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.

Android Solutions


Solution 1 - Android

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.

Solution 2 - Android

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

Solution 3 - Android

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" />

Solution 4 - Android

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);

Solution 5 - Android

I am using a com.google.android.material.bottomnavigation.BottomNavigationView (not the same as OP's) and I tried a variety of the suggested solutions above, but the only thing that worked was setting app:itemBackground and app:itemIconTint to my selector color worked for me.

        <com.google.android.material.bottomnavigation.BottomNavigationView
            style="@style/BottomNavigationView"
            android:foreground="?attr/selectableItemBackground"
            android:theme="@style/BottomNavigationView"
            app:itemBackground="@color/tab_color"
            app:itemIconTint="@color/tab_color"
            app:itemTextColor="@color/bottom_navigation_text_color"
            app:labelVisibilityMode="labeled"
            app:menu="@menu/bottom_navigation" />

My color/tab_color.xml uses android:state_checked

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

and I am also using a selected state color for color/bottom_navigation_text_color.xml

enter image description here

Not totally relevant here but for full transparency, my BottomNavigationView style is as follows:

    <style name="BottomNavigationView" parent="Widget.Design.BottomNavigationView">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">@dimen/bottom_navigation_height</item>
        <item name="android:layout_gravity">bottom</item>
        <item name="android:textSize">@dimen/bottom_navigation_text_size</item>
    </style>

Solution 6 - Android

It's too late to answer but might be helpful for someone. I was doing a very silly mistake, I was using a selector file named as bottom_color_nav.xml for Select and unselect color change but still it was not reflecting any color change in BottomNavigationView.

Then I realize, I was returning false in onNavigationItemSelected method. It will work fine if you'll return true in this method.

Solution 7 - Android

In order to set textColor, BottomNavigationView has two style properties you can set directly from the xml:

  • itemTextAppearanceActive
  • itemTextAppearanceInactive

In your layout.xml file:

<com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bnvMainNavigation"
            style="@style/NavigationView"/>
  

In your styles.xml file:

    <style name="NavigationView" parent="Widget.MaterialComponents.BottomNavigationView">
      <item name="itemTextAppearanceActive">@style/ActiveText</item>
      <item name="itemTextAppearanceInactive">@style/InactiveText</item>
    </style>
    <style name="ActiveText">
      <item name="android:textColor">@color/colorPrimary</item>
    </style>
    <style name="InactiveText">
      <item name="android:textColor">@color/colorBaseBlack</item>
    </style>

<!-- end snippet -->

Solution 8 - Android

Try using android:state_enabled rather than android:state_selected for the selector item attributes.

Solution 9 - Android

This will work:

setItemBackgroundResource(android.R.color.holo_red_light)

Solution 10 - Android

Instead of creating selector, Best way to create a style.

<style name="AppTheme.BottomBar">
    <item name="colorPrimary">@color/colorAccent</item> 
</style>

and to change the text size, selected or non selected.

<dimen name="design_bottom_navigation_text_size" tools:override="true">11sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">12sp</dimen>

Enjoy Android!

Solution 11 - Android

As the folder structure has changed, the tab_color.xml belongs to res > drawable now which can handle selectors. From there on the accepted solution works.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJavadView Question on Stackoverflow
Solution 1 - AndroidKamran AhmedView Answer on Stackoverflow
Solution 2 - AndroidKishore ReddyView Answer on Stackoverflow
Solution 3 - AndroiddzikovskyyView Answer on Stackoverflow
Solution 4 - AndroidMax ZonovView Answer on Stackoverflow
Solution 5 - AndroidSampsonView Answer on Stackoverflow
Solution 6 - Androidajay singhView Answer on Stackoverflow
Solution 7 - AndroidNicola GallazziView Answer on Stackoverflow
Solution 8 - AndroidAbtin GramianView Answer on Stackoverflow
Solution 9 - AndroidKUNAL DASView Answer on Stackoverflow
Solution 10 - AndroidShahbaz AhmedView Answer on Stackoverflow
Solution 11 - AndroidBenedict LangView Answer on Stackoverflow