底部导航视图中选定选项卡的颜色

193

我正在将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>

我会感激任何帮助。

12个回答

374

在制作选择器时,始终将默认状态放在最后,否则只会使用默认状态。您需要按以下顺序重新排列选择器中的项目:

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


98
将其添加至:<android.support.design.widget.BottomNavigationView app:itemIconTint="@drawable/nav_item_color_state" app:itemTextColor="@drawable/nav_item_color_state" /> - dianakarenms
1
在我的情况下,我需要生成动态菜单,但这个解决方案不起作用。唯一有效的解决方案是手动设置菜单项 https://dev59.com/3Gw15IYBdhLWcg3wVKJ1#7106111 - Rafael
13
"state_checked not state_selected". 真是省时的工具:) 谢谢! - Piotr Ślesarew
4
请将 @drawable 替换为 <android.support.design.widget.BottomNavigationView app:itemIconTint="@color/nav_item_color_state" app:itemTextColor="@color/nav_item_color_state" />。这样可以添加颜色状态到底部导航栏的图标和文字颜色上。 - Anton Makov
7
对于像我这样被卡住的人,我不得不在“res”目录下创建一个“color”目录,并将此文件放入其中。 - Tayyab Mazhar
显示剩余3条评论

108

1.res中创建一个名为color的文件夹(类似于drawable)。

2.右键单击颜色文件夹。选择new-> color resource file-> create color.xml file (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: 文件结构


这让我节省了很多时间。非常棒的解释。 - OtienoSamwel

74
BottomNavigationView使用应用于选定选项卡的主题中的colorPrimary,并且使用android:textColorSecondary来设置非活动选项卡图标的色调。
因此,您可以创建一个带有首选主颜色的样式,并将其设置为xml布局文件中的BottomNavigationView的主题。

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”代替。 - Mahdi Moqadasi
2
这是最佳答案,“selector”方法使用“darker_gray”作为非活动选项卡颜色,与原始颜色不同。此外,android:textColorSecondary 对我有效。谢谢! - Sam Chen

26

如果您想通过编程的方式更改图标和文本颜色:

ColorStateList iconColorStates = 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(iconColorStates);
navigation.setItemTextColor(iconColorStates);

2
你让我的一天变得美好 :) 运行得非常顺畅 - ΩlostA

19

我正在使用一个com.google.android.material.bottomnavigation.BottomNavigationView(与OP不同),我尝试了上面建议的各种解决方案,但唯一有效的方法是将app:itemBackgroundapp: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>

颜色/标签颜色.xml?你能解释一下吗? - Kumar Santanu
我在上面的回答中发布了 color/tab_color.xml,这是颜色选择器文件。 - Sampson

10

虽然回答可能已经晚了,但对某些人可能仍有帮助。

我犯了一个非常愚蠢的错误,我使用了一个名为bottom_color_nav.xml的选择器文件来进行选中和取消选中颜色的更改,但在BottomNavigationView中它仍然没有反映任何颜色变化。

后来我意识到,在onNavigationItemSelected方法中我返回了false。如果在该方法中返回true,它将正常工作。


我花了将近30分钟,尝试了每一个解决方案, 最后才发现我返回了False,这是我的错误。 - undefined

7
为了设置文本颜色,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>

1
不确定为什么无法使这个解决方案工作,但接受的解决方案确实有效。此外,任何想要查看itemIconTintitemTextColor的默认材料样式的人,请查看@color/mtrl_navigation_bar_item_tint - lasec0203

3

尝试使用android:state_enabled而不是android:state_selected作为选择器项目属性。


如问题所述,我也尝试了state_enabled,但这不是与此特定小部件一起使用的正确状态属性。问题就像答案中所述:1. 排序错误(默认状态应该是选择器中的最后一个项目)2. state_checked是应该与BottomNavigationView一起使用的正确状态属性。 - Javad

1

由于文件夹结构已更改,tab_color.xml 现在属于 res > drawable,可以处理选择器。从那里开始,接受的解决方案就可以工作了。


1

This will work:

setItemBackgroundResource(android.R.color.holo_red_light)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接