Couleur de l'onglet sélectionné dans la vue de navigation inférieure

142

J'ajoute un BottomNavigationViewà un projet et j'aimerais avoir une couleur de texte (et d'icône) différente pour l'onglet sélectionné (pour obtenir un effet d'onglets non sélectionnés en grisé). L'utilisation d'une couleur différente android:state_selected="true"dans un fichier de ressources de sélecteur de couleurs ne semble pas fonctionner. J'ai également essayé d'avoir des entrées d'articles supplémentaires avec android:state_focused="true"ou android:state_enabled="true"sans effet malheureusement. J'ai également essayé de définir l' state_selectedattribut sur false (explicitement) pour la couleur par défaut (non sélectionnée), sans succès.

Voici comment j'ajoute la vue à ma mise en page:

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

Voici mon sélecteur de couleur ( 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>

Et ma ressource de menu ( 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>

J'apprécierais toute aide.

Javad Sadeqzadeh
la source

Réponses:

310

Lors de la création d'un selector, conservez toujours l'état par défaut à la fin, sinon seul l'état par défaut serait utilisé. Vous devez réorganiser les éléments dans votre sélecteur comme suit:

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

Et l'état à utiliser ne l' BottomNavigationBarest state_checkedpas state_selected.

Kamran Ahmed
la source
77
ajoutez-le sur <android.support.design.widget.BottomNavigationView app: itemIconTint = "@ drawable / nav_item_color_state" app: itemTextColor = "@ drawable / nav_item_color_state" />
dianakarenms
1
Dans mon cas, j'avais besoin de générer un menu dynamique, et cette solution n'a pas fonctionné. La seule solution de travail était de définir manuellement les éléments de menu stackoverflow.com/a/7106111/2098878
Rafael
9
"state_checked not state_selected". Quel gain de temps :) Merci!
Piotr Ślesarew
3
ajoutez-le sur <android.support.design.widget.BottomNavigationView app: itemIconTint = "@ color / nav_item_color_state" app: itemTextColor = "@ color / nav_item_color_state" /> au lieu de @ drawable
Anton Makov
1
Pour tous ceux qui sont restés coincés comme moi, j'ai dû créer un répertoire "color" dans "res", et y mettre ce fichier.
Tayyab Mazhar
67

1. À l'intérieur de res créer un dossier avec la couleur du nom (comme drawable)

2. Cliquez avec le bouton droit sur le dossier de couleurs. Sélectionnez nouveau-> fichier de ressources de couleur-> créer un fichier color.xml (bnv_tab_item_foreground) (Figure 1: Structure de fichier)

3. Copiez et collez 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: Structure des fichiers:

Figure 1: Structure des fichiers

Kishore Reddy
la source
53

BottomNavigationViewutilise colorPrimary du thème appliqué pour l'onglet sélectionné et il l' utilise android:textColorSecondary pour la teinte de l'icône de l'onglet inactif.

Ainsi, vous pouvez créer un style avec la couleur primaire préférée et le définir comme thème BottomNavigationViewdans un fichier de mise en page 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
la source
3
android:textColorSecondaryne fonctionne pas. devrait utiliser à la android:colorForegroundplace
Mahdi Moqadasi
C'est la meilleure réponse, la méthode "selector" utilise "darker_gray" comme couleur d'onglet inactive qui est différente de celle d'origine. Fonctionne aussi android:textColorSecondarypour moi. Merci!
Sam Chen
9

Si vous souhaitez modifier les couleurs des icônes et des textes par programmation:

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
la source
5

Il est trop tard pour répondre, mais cela pourrait être utile pour quelqu'un. Je faisais une erreur très stupide, j'utilisais un fichier de sélection nommé bottom_color_nav.xml pour sélectionner et désélectionner le changement de couleur, mais il ne reflétait toujours aucun changement de couleur dans BottomNavigationView.

Ensuite, je me rends compte, je retournais false dans la méthode onNavigationItemSelected . Cela fonctionnera bien si vous retournez true dans cette méthode.

ajay singh
la source
2

Essayez d'utiliser android:state_enabledplutôt que android:state_selectedpour les attributs d'élément de sélection.

Abtin Gramian
la source
Comme mentionné dans la question, j'ai également essayé state_enabled, mais ce n'est pas l'attribut d'état correct à utiliser avec ce widget spécifique. Le problème était ce qui a été mentionné dans la réponse: 1. L'ordre était erroné (l'état par défaut doit être le dernier élément du sélecteur) 2. state_checked est l'attribut d'état correct à utiliser avec BottomNavigationView.
Javad Sadeqzadeh
2

J'utilise un com.google.android.material.bottomnavigation.BottomNavigationView(pas le même que les OP) et j'ai essayé une variété des solutions suggérées ci-dessus, mais la seule chose qui a fonctionné était le réglage app:itemBackgroundet app:itemIconTintla couleur de mon sélecteur a fonctionné pour moi.

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

Mes color/tab_color.xmlutilisationsandroid: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>

et j'utilise également une couleur d'état sélectionnée pour color/bottom_navigation_text_color.xml

entrez la description de l'image ici

Pas totalement pertinent ici mais pour une transparence totale, mon BottomNavigationViewstyle est le suivant:

    <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
la source
1

Afin de définir textColor, BottomNavigationViewa deux propriétés de style que vous pouvez définir directement à partir du 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
la source
0

Cela fonctionnera:

setItemBackgroundResource(android.R.color.holo_red_light)
KUNAL DAS
la source
0

Au lieu de créer un sélecteur, meilleure façon de créer un style.

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

et pour changer la taille du texte, sélectionné ou non.

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

Profitez d'Android!

Shahbaz Ahmed
la source