Kolor wybranej zakładki w dolnym widoku nawigacji

142

Dodaję BottomNavigationViewdo projektu i chciałbym mieć inny kolor tekstu (i odcienia ikon) dla wybranej zakładki (aby uzyskać efekt szarzenia niewybranych zakładek). android:state_selected="true"Wydaje się, że użycie innego koloru w pliku zasobów selektora kolorów nie działa. Próbowałem też wprowadzić dodatkowe pozycje z efektem android:state_focused="true"lub android:state_enabled="true"bez efektu. Próbowałem również ustawić state_selectedatrybut na false (jawnie) dla domyślnego (niewybranego) koloru, bez powodzenia.

Oto jak dodaję widok do mojego układu:

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

Oto mój selektor kolorów ( 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>

I mój zasób 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>

Byłbym wdzięczny za każdą pomoc.

Javad Sadeqzadeh
źródło

Odpowiedzi:

310

Podczas tworzenia selectorzawsze zachowuj stan domyślny na końcu, w przeciwnym razie zostanie użyty tylko stan domyślny. Musisz zmienić kolejność elementów w swoim selektorze jako:

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

A stan, który ma być używany, nie BottomNavigationBarjest .state_checkedstate_selected

Kamran Ahmed
źródło
77
dodaj go do aplikacji <android.support.design.widget.BottomNavigationView: itemIconTint = "@ drawable / nav_item_color_state" app: itemTextColor = "@ drawable / nav_item_color_state" />
dianakarenms
1
W moim przypadku musiałem wygenerować dynamiczne menu, a to rozwiązanie nie działało. Jedynym działającym rozwiązaniem było ręczne ustawianie elementów menu stackoverflow.com/a/7106111/2098878
Rafael
9
„state_checked not state_selected”. Co za oszczędność czasu :) Dzięki!
Piotr Ślesarew
3
dodaj go do aplikacji <android.support.design.widget.BottomNavigationView: itemIconTint = "@ color / nav_item_color_state" app: itemTextColor = "@ color / nav_item_color_state" /> zamiast @ drawable
Anton Makov
1
Dla każdego, kto utknął jak ja, musiałem utworzyć katalog „color” w „res” i umieścić tam ten plik.
Tayyab Mazhar
67

1. Wewnątrz res utwórz folder z nazwą koloru (jak do rysowania)

2. Kliknij prawym przyciskiem myszy folder kolorów. Wybierz nowy-> plik zasobów koloru-> utwórz plik color.xml (bnv_tab_item_foreground) (Rysunek 1: Struktura pliku)

3. Skopiuj i wklej 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>

Rysunek 1: Struktura pliku:

Rysunek 1: Struktura plików

Kishore Reddy
źródło
53

BottomNavigationViewużywa colorPrimary z motywu zastosowanego dla wybranej karty i używa android:textColorSecondary do przyciemnienia ikony nieaktywnej karty.

Możesz więc stworzyć styl z preferowanym kolorem podstawowym i ustawić go jako motyw swojego BottomNavigationVieww pliku układu 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
źródło
3
android:textColorSecondarynie działa. powinien użyć android:colorForegroundzamiast tego
Mahdi Moqadasi
To najlepsza odpowiedź, metoda "selector" używa "darker_gray" jako koloru nieaktywnej zakładki, który różni się od oryginalnego. U android:textColorSecondarymnie też działa. Dzięki!
Sam Chen
9

Jeśli chcesz programowo zmienić kolory ikon i tekstów:

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
źródło
5

Za późno na odpowiedź, ale może to być pomocne dla kogoś. Robiłem bardzo głupi błąd, używałem pliku selektora o nazwie bottom_color_nav.xml do zmiany koloru Wybierz i odznacz, ale nadal nie odzwierciedlał on żadnej zmiany koloru w BottomNavigationView.

Wtedy zdaję sobie sprawę, że zwracałem false w metodzie onNavigationItemSelected . Będzie działać dobrze, jeśli zwrócisz true w tej metodzie.

ajay singh
źródło
2

Spróbuj użyć android:state_enabledzamiast android:state_selectedatrybutów pozycji selektora.

Abtin Gramian
źródło
Jak wspomniano w pytaniu, próbowałem również state_enabled, ale nie jest to właściwy atrybut stanu do użycia z tym konkretnym widżetem. Problem dotyczy tego, o czym wspomniano w odpowiedzi: 1. Kolejność była nieprawidłowa (stan domyślny powinien być ostatnim elementem selektora) 2. state_checked to poprawny atrybut stanu, który ma być używany z BottomNavigationView.
Javad Sadeqzadeh,
1

Aby ustawić textColor, BottomNavigationViewma dwie właściwości stylu, które możesz ustawić bezpośrednio z 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
źródło
1

Używam com.google.android.material.bottomnavigation.BottomNavigationView(nie tego samego co OP) i wypróbowałem różne sugerowane rozwiązania powyżej, ale jedyną rzeczą, która działała, było ustawienie app:itemBackgroundi app:itemIconTintkolor mojego selektora działał dla mnie.

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

Moje color/tab_color.xmlzastosowaniaandroid: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>

i używam również wybranego koloru stanu dla color/bottom_navigation_text_color.xml

wprowadź opis obrazu tutaj

Nie jest to całkowicie istotne, ale dla pełnej przejrzystości mój BottomNavigationViewstyl jest następujący:

    <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
źródło
0

To zadziała:

setItemBackgroundResource(android.R.color.holo_red_light)
KUNAL DAS
źródło
0

Zamiast tworzyć selektor, najlepszy sposób na stworzenie stylu.

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

i zmienić rozmiar tekstu, zaznaczony lub niewybrany.

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

Ciesz się Androidem!

Shahbaz Ahmed
źródło