Цвет выбранной вкладки в нижнем окне навигации

146

Я добавляю BottomNavigationViewв проект, и я хотел бы иметь другой цвет текста (и оттенка значка) для выбранной вкладки (чтобы добиться эффекта затемнения невыбранных вкладок). Использование другого цвета android:state_selected="true"в файле ресурсов селектора цвета, похоже, не работает. Я также попытался добавить дополнительные элементы с android:state_focused="true"или android:state_enabled="true", к сожалению, безрезультатно. Также попытался установить для state_selectedатрибута значение false (явно) для цвета по умолчанию (не выбранный), но безуспешно.

Вот как я добавляю представление в свой макет:

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

Вот мой селектор цвета ( 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>

И мой ресурс меню ( 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>

Буду признателен за любую помощь.

Джавад Садекзаде
источник

Ответы:

323

При создании selectorвсегда сохраняйте состояние по умолчанию в конце, иначе будет использоваться только состояние по умолчанию. Вам нужно изменить порядок элементов в вашем селекторе следующим образом:

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

И состояние, с которым можно работать, BottomNavigationBar- state_checkedнет state_selected.

Камран Ахмед
источник
82
добавьте его в приложение <android.support.design.widget.BottomNavigationView: itemIconTint = "@ drawable / nav_item_color_state" app: itemTextColor = "@ drawable / nav_item_color_state" />
dianakarenms
1
В моем случае мне нужно было создать динамическое меню, и это решение не сработало. Работает только раствор вручную настройки пунктов меню stackoverflow.com/a/7106111/2098878
Rafael
10
"state_checked not state_selected". Какая экономия времени :) Спасибо!
Петр Слесарев
4
добавьте его в приложение <android.support.design.widget.BottomNavigationView: itemIconTint = "@ color / nav_item_color_state" app: itemTextColor = "@ color / nav_item_color_state" /> вместо @ drawable
Антон Маков
2
Для тех, кто застрял, как я, мне пришлось создать каталог «color» в «res» и поместить туда этот файл.
Тайяб Мажар
71

1. Внутри res создайте папку с цветом имени (например, drawable)

2. Щелкните правой кнопкой мыши папку цветов. Выберите новый-> файл ресурсов цвета-> создать файл color.xml (bnv_tab_item_foreground) (Рисунок 1: Структура файла)

3. Скопируйте и вставьте 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>

Рисунок 1: Файловая структура:

Рисунок 1: Файловая структура

Кишор Редди
источник
60

BottomNavigationViewиспользует colorPrimary из темы, примененной к выбранной вкладке, и использует android:textColorSecondary оттенок значка неактивной вкладки.

Таким образом, вы можете создать стиль с предпочтительным основным цветом и установить его в качестве темы для себя BottomNavigationViewв файле макета 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" />
Дзиковский
источник
4
android:textColorSecondaryне работает. следует использовать android:colorForegroundвместо этого
Махди Мокадаси
1
Это лучший ответ, метод «селектор» использует «darker_gray» в качестве неактивного цвета вкладки, который отличается от исходного цвета. У android:textColorSecondaryменя тоже работает. Благодарность!
Сэм Чен
11

Если вы хотите программно изменить цвета значков и текстов:

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);
Макс Зонов
источник
6

Слишком поздно отвечать, но может быть кому-то полезно. Я совершил очень глупую ошибку, я использовал файл селектора с именем bottom_color_nav.xml для выбора и отмены выбора изменения цвета, но все же он не отражал никаких изменений цвета в BottomNavigationView.

Затем я понимаю, что возвращал false в методе onNavigationItemSelected . Он будет работать нормально, если вы вернете в этом методе true.

Аджай Сингх
источник
3

Я использую com.google.android.material.bottomnavigation.BottomNavigationView(не такой, как OP), и я пробовал множество предложенных выше решений, но единственное, что сработало, - это настройка, app:itemBackgroundи app:itemIconTintмой цвет селектора сработал для меня.

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

Мое color/tab_color.xmlиспользование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>

и я также использую выбранный цвет состояния для color/bottom_navigation_text_color.xml

введите описание изображения здесь

Это не совсем актуально, но для полной прозрачности мой BottomNavigationViewстиль таков:

    <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
источник
2

Попробуйте использовать android:state_enabledвместо android:state_selectedатрибутов элемента селектора.

Абтин Грамиан
источник
Как упоминалось в вопросе, я также пробовал state_enabled, но это не тот атрибут состояния, который нужно использовать с этим конкретным виджетом. Проблема заключалась в том, что было упомянуто в ответе: 1. Неправильный порядок (состояние по умолчанию должно быть последним элементом в селекторе) 2. state_checked - это правильный атрибут состояния, который будет использоваться с BottomNavigationView.
Джавад Садекзаде
1

Чтобы установить textColor, у BottomNavigationViewнего есть два свойства стиля, которые вы можете установить непосредственно из xml:

  • itemTextAppearanceActive
  • itemTextAppearanceInactive

В вашем файле layout.xml:

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

В вашем файле styles.xml:

    <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>
Никола Галлацци
источник
0

Это будет работать:

setItemBackgroundResource(android.R.color.holo_red_light)
КУНАЛ ДАС
источник
0

Вместо создания селектора, лучший способ создать стиль.

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

и для изменения размера текста, выбранного или невыделенного.

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

Наслаждайтесь Android!

Шахбаз Ахмед
источник