Cor da guia selecionada na Vista de navegação inferior

142

Estou adicionando um BottomNavigationViewa um projeto e gostaria de ter uma cor de texto (e tonalidade de ícone) diferente para a guia selecionada (para obter o efeito de guias não selecionadas em cinza). O uso de uma cor diferente android:state_selected="true"em um arquivo de recurso do seletor de cores não parece funcionar. Também tentei ter entradas de itens adicionais com android:state_focused="true"ou android:state_enabled="true", infelizmente, sem efeito. Também tentei definir o state_selectedatributo como false (explicitamente) para a cor padrão (não selecionada), sem sorte.

Aqui está como adiciono a visualização ao meu 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" />

Aqui está o meu seletor de cores ( 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>

E meu recurso 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>

Eu apreciaria qualquer ajuda.

Javad Sadeqzadeh
fonte

Respostas:

310

Ao criar um selector, sempre mantenha o estado padrão no final, caso contrário, apenas o estado padrão seria usado. Você precisa reordenar os itens no seu seletor 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>

E o estado a ser usado não BottomNavigationBaré .state_checkedstate_selected

Kamran Ahmed
fonte
77
adicione-o no <android.support.design.widget.BottomNavigationView app: itemIconTint = "@ drawable / nav_item_color_state" app: itemTextColor = "@ drawable / nav_item_color_state" />
dianakarenms
1
No meu caso, eu precisava gerar menu dinâmico, e esta solução não funcionou. A única solução de trabalho foi definir manualmente itens de menu stackoverflow.com/a/7106111/2098878
Rafael
9
"state_checked não state_selected". Que economia de tempo :) Obrigado!
Piotr Ślesarew
3
adicioná-lo em <android.support.design.widget.BottomNavigationView app: itemIconTint = "@ cor / nav_item_color_state" app: itemTextColor = "@ cor / nav_item_color_state" /> em vez de @ drawable
Anton Makov
1
Para quem ficou preso como eu, tive que criar um diretório "color" em "res" e colocar esse arquivo lá.
Tayyab Mazhar
66

1. Dentro res criar pasta com nome da cor (como drawable)

2. Clique com o botão direito na pasta colorida. Selecione novo-> arquivo de recursos de cores-> crie o arquivo color.xml (bnv_tab_item_foreground) (Figura 1: Estrutura do arquivo)

3. Copie e cole 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: Estrutura do arquivo:

Figura 1: Estrutura do arquivo

Kishore Reddy
fonte
53

BottomNavigationViewusa colorPrimary do tema aplicado para a guia selecionada e usa android:textColorSecondary para a tonalidade ícone do separador inativo.

Assim, você pode criar um estilo com a cor primária preferida e configurá-lo como tema para o seu BottomNavigationViewem um arquivo de layout 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
fonte
3
android:textColorSecondarynão funciona. deve usar android:colorForegroundvez
Mahdi Moqadasi
Essa é a melhor resposta, o método "seletor" usa "darker_gray" como a cor da guia inativa, que é diferente da original. Também android:textColorSecondaryfunciona para mim. Obrigado!
Sam Chen
9

Se você deseja alterar as cores dos ícones e textos por meio de programação:

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

É muito tarde para responder, mas pode ser útil para alguém. Eu estava cometendo um erro muito bobo, estava usando um arquivo seletor chamado bottom_color_nav.xml para Selecionar e desmarcar alteração de cor, mas ainda assim não estava refletindo nenhuma alteração de cor no BottomNavigationView.

Então percebo que estava retornando false no método onNavigationItemSelected . Funcionará bem se você retornar verdadeiro neste método.

ajay singh
fonte
2

Tente usar android:state_enabledao invés android:state_selecteddos atributos do item seletor.

Abtin Gramian
fonte
Conforme mencionado na pergunta, tentei também state_enabled, mas esse não é o atributo de estado correto a ser usado com esse widget específico. O problema foi mencionado na resposta: 1. A ordem estava errada (o estado padrão deve ser o último item no seletor) 2. state_checked é o atributo de estado correto a ser usado com BottomNavigationView.
Javad Sadeqzadeh
1

Para definir textColor, BottomNavigationViewpossui duas propriedades de estilo que você pode definir diretamente no 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
fonte
1

Estou usando um com.google.android.material.bottomnavigation.BottomNavigationView(não o mesmo que OP) e tentei várias das soluções sugeridas acima, mas a única coisa que funcionou foi a configuração app:itemBackgrounde app:itemIconTinta cor do meu seletor funcionou para mim.

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

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

e também estou usando uma cor de estado selecionada para color/bottom_navigation_text_color.xml

insira a descrição da imagem aqui

Não é totalmente relevante aqui, mas para total transparência, meu BottomNavigationViewestilo é o seguinte:

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

Isso funcionará:

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

Em vez de criar o seletor, a melhor maneira de criar um estilo.

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

e para alterar o tamanho do texto, selecionado ou não selecionado.

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

Aproveite o Android!

Shahbaz Ahmed
fonte