Color de la pestaña seleccionada en la Vista de navegación inferior

142

Estoy agregando un BottomNavigationViewa un proyecto, y me gustaría tener un color de texto diferente (y tinte de icono) para la pestaña seleccionada (para lograr el efecto de pestañas no seleccionadas en gris). Usar un color diferente con android:state_selected="true"un archivo de recursos de selector de color no parece funcionar. También intenté tener entradas de elementos adicionales con android:state_focused="true"o android:state_enabled="true", sin efecto, desafortunadamente. También intenté establecer el state_selectedatributo en falso (explícitamente) para el color predeterminado (no seleccionado), sin suerte.

Así es como agrego la vista a mi diseño:

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

Aquí está mi selector de color ( 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>

Y mi recurso de menú ( 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>

Apreciaría cualquier ayuda.

Javad Sadeqzadeh
fuente

Respuestas:

310

Mientras realiza un selector, mantenga siempre el estado predeterminado al final, de lo contrario solo se usaría el estado predeterminado. Debe reordenar los elementos en su selector como:

<?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>

Y el estado para ser utilizado no lo BottomNavigationBares .state_checkedstate_selected

Kamran Ahmed
fuente
77
agréguelo en la aplicación <android.support.design.widget.BottomNavigationView: itemIconTint = "@ drawable / nav_item_color_state" app: itemTextColor = "@ drawable / nav_item_color_state" />
dianakarenms
1
En mi caso, necesitaba generar un menú dinámico, y esta solución no funcionó. La única solución de trabajo era configurar manualmente los elementos del menú stackoverflow.com/a/7106111/2098878
Rafael
9
"state_checked no state_selected". ¡Qué ahorro de tiempo :) Gracias!
Piotr Ślesarew
3
agréguelo en la aplicación <android.support.design.widget.BottomNavigationView: itemIconTint = "@ color / nav_item_color_state" app: itemTextColor = "@ color / nav_item_color_state" /> en lugar de @ drawable
Anton Makov el
1
Para cualquiera que se atascara como yo, tuve que crear un directorio de "color" en "res" y poner este archivo allí.
Tayyab Mazhar
66

1. Dentro de resolución crear carpeta con color de nombre (como dibujable)

2. Haga clic derecho en la carpeta de color. Seleccione nuevo-> archivo de recursos de color-> crear archivo color.xml (bnv_tab_item_foreground) (Figura 1: Estructura del archivo)

3. Copie y pegue 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>

Figura 1: Estructura del archivo:

Figura 1: Estructura del archivo

Kishore Reddy
fuente
53

BottomNavigationViewusa colorPrimary del tema aplicado para la pestaña seleccionada y usa android:textColorSecondary el tinte del icono de pestaña inactiva.

Por lo tanto, puede crear un estilo con el color primario preferido y establecerlo como un tema BottomNavigationViewen un archivo de diseño xml.

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" />
dzikovskyy
fuente
3
android:textColorSecondaryno funciona. debería usar android:colorForegrounden su lugar
Mahdi Moqadasi
Esta es la mejor respuesta, el método "selector" utiliza "darker_gray" como el color de la pestaña inactiva, que es diferente del original. También android:textColorSecondaryfunciona para mi. ¡Gracias!
Sam Chen
9

Si desea cambiar los colores de iconos y textos mediante programación:

ColorStateList iconsColorStates = 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")
            });

    ColorStateList textColorStates = 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(iconsColorStates);
    navigation.setItemTextColor(textColorStates);
Max Zonov
fuente
5

Es demasiado tarde para responder, pero podría ser útil para alguien. Estaba cometiendo un error muy tonto, estaba usando un archivo selector llamado bottom_color_nav.xml para Seleccionar y deseleccionar el cambio de color, pero aún así no reflejaba ningún cambio de color en BottomNavigationView.

Entonces me doy cuenta de que estaba devolviendo false en el método onNavigationItemSelected . Funcionará bien si devuelve verdadero en este método.

Ajay Singh
fuente
2

Intente usar en android:state_enabledlugar de android:state_selectedlos atributos del elemento selector.

Abtin Gramian
fuente
Como se mencionó en la pregunta, también probé state_enabled, pero ese no es el atributo de estado correcto que se utilizará con este widget específico. El problema era lo que se mencionaba en la respuesta: 1. El orden era incorrecto (el estado predeterminado debería ser el último elemento del selector) 2. state_checked es el atributo de estado correcto que se utilizará con BottomNavigationView.
Javad Sadeqzadeh
1

Para establecer textColor, BottomNavigationViewtiene dos propiedades de estilo que puede establecer directamente desde el 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>
Nicola Gallazzi
fuente
1

Estoy usando un com.google.android.material.bottomnavigation.BottomNavigationView(no es lo mismo que OP) y probé una variedad de las soluciones sugeridas anteriormente, pero lo único que funcionó fue la configuración app:itemBackgroundy app:itemIconTintel color de mi selector funcionó para mí.

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

Mis color/tab_color.xmlusosandroid: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>

y también estoy usando un color de estado seleccionado para color/bottom_navigation_text_color.xml

ingrese la descripción de la imagen aquí

No es totalmente relevante aquí pero para una total transparencia, mi BottomNavigationViewestilo es el siguiente:

    <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>
Sampson
fuente
0

Esto funcionará:

setItemBackgroundResource(android.R.color.holo_red_light)
KUNAL DAS
fuente
0

En lugar de crear un selector, la mejor manera de crear un estilo.

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

y para cambiar el tamaño del texto, seleccionado o no seleccionado.

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

¡Disfruta de Android!

Shahbaz Ahmed
fuente