BottomNavigationView自定义图标无法高亮问题咨询
这个问题我之前也踩过坑,核心原因是BottomNavigationView需要通过状态选择器(StateListDrawable)来区分图标选中/未选中的状态,单纯设置单张PNG图标,系统没法自动切换高亮样式。下面给你两种实用的解决方法:
方法一:使用状态选择器图标(适合需要不同图标样式的场景)
如果你的选中/未选中图标有完全不同的设计(比如选中时图标带动效变形),可以用这种方式:
准备资源:
给每个导航项准备两张PNG图标:一张是未选中状态(比如浅灰色),一张是选中状态(比如你的主题强调色),例如:ic_home_unselected.png(未选中样式)ic_home_selected.png(选中样式)
创建状态选择器XML:
在drawable目录下新建一个XML文件,比如ic_home_selector.xml,内容如下:<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 选中状态显示的图标 --> <item android:drawable="@drawable/ic_home_selected" android:state_checked="true"/> <!-- 未选中状态显示的图标 --> <item android:drawable="@drawable/ic_home_unselected" android:state_checked="false"/> </selector>修改Menu配置:
把原来menu item里的android:icon指向这个选择器,同时删掉item里多余的layout_width、layout_height属性(menu item不需要这些布局属性):<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/navigation_home" android:icon="@drawable/ic_home_selector" android:title="@string/title_home" /> <item android:id="@+id/navigation_dashboard" android:icon="@drawable/ic_dashboard_selector" android:title="@string/title_dashboard" /> <!-- 其他导航项同理配置 --> </menu>
方法二:使用颜色Tint实现(复用单张图标,更高效)
如果只是需要通过颜色区分选中状态,这种方式更省心,不需要准备两张图标:
创建颜色选择器XML:
在res/color目录下新建bottom_nav_icon_tint.xml(没有color目录就新建一个),内容如下:<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 选中状态的图标颜色 --> <item android:color="@color/your_theme_accent_color" android:state_checked="true"/> <!-- 未选中状态的图标颜色 --> <item android:color="@color/gray_light" android:state_checked="false"/> </selector>配置BottomNavigationView:
你可以在XML布局里直接设置,或者在代码中配置:- XML方式:
<com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_nav" android:layout_width="match_parent" android:layout_height="wrap_content" app:menu="@menu/bottom_nav_menu" app:itemIconTint="@color/bottom_nav_icon_tint" app:itemTextColor="@color/bottom_nav_icon_tint"/> <!-- 文字颜色也可以同步使用这个选择器 --> - 代码方式(Kotlin):
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_nav) bottomNav.itemIconTintList = ContextCompat.getColorStateList(this, R.color.bottom_nav_icon_tint)
- XML方式:
注意事项:
确保你的PNG图标是单色透明底的风格,这样tint才能完美覆盖颜色。如果图标本身是多色的,tint会把所有颜色替换成设置的颜色,可能达不到预期效果。
额外小提示
- 菜单item里不要加
layout_width、layout_height这类属性,它们不属于menu的配置项,会导致无效甚至报错; - 如果用的是Material Design的官方图标,建议直接用Vector Asset导入矢量图,比PNG更灵活,tint效果也更好;
- 可以通过
app:itemIconSize调整图标大小,适配你的布局需求。
内容的提问来源于stack exchange,提问作者thomi
相关产品推荐
相关产品推荐

