Android底部导航:实现各Tab选中时图标与标题自定义变色
你遇到的问题其实是BottomNavigationView的默认行为导致的——它会统一应用全局的itemTextColor和itemIconTint来控制所有Tab的样式,单独在MenuItem的Selector里设置的color属性不会被识别到文字上。下面是具体的解决方案:
步骤1:移除全局颜色属性
先把布局里的app:itemTextColor和app:itemIconTint删掉,避免全局样式覆盖我们的自定义设置:
<com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" app:menu="@menu/main_bottom_navigation" style="@style/BottomNavigationView" app:labelVisibilityMode="labeled" android:layout_alignParentBottom="true" />
步骤2:为每个Tab创建单独的颜色Selector
给每个Tab分别创建文字颜色的Selector(放在res/color/目录下),比如:
- 测量Tab的颜色选择器
tab_measure_color_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/green_your_custom" android:state_checked="true"/> <item android:color="@color/gray_default" android:state_checked="false"/> </selector>
- 个人中心Tab的颜色选择器
tab_profile_color_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/green_your_custom" android:state_checked="true"/> <item android:color="@color/gray_default" android:state_checked="false"/> </selector>
图标Selector你已经写好了,确保每个图标的Selector对应正确的选中/未选中状态即可。
步骤3:代码中手动为每个Tab设置样式
在Activity/Fragment的初始化代码里,找到每个Tab对应的子View(图标和标题),手动设置它们的Selector:
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_navigation) // 处理"测量"Tab val measureItem = bottomNav.menu.findItem(R.id.action_measure) val measureView = bottomNav.findViewById<View>(R.id.action_measure) // 获取内部的图标和标题View(使用Material组件的内部ID) val measureIcon = measureView.findViewById<ImageView>(com.google.android.material.R.id.icon) val measureTitle = measureView.findViewById<TextView>(com.google.android.material.R.id.title) // 设置图标Selector measureIcon.setImageResource(R.drawable.bottom_bar_measure_selector) // 设置文字颜色Selector measureTitle.setTextColor(ContextCompat.getColorStateList(this, R.color.tab_measure_color_selector)) // 处理"个人中心"Tab val profileItem = bottomNav.menu.findItem(R.id.action_profile) val profileView = bottomNav.findViewById<View>(R.id.action_profile) val profileIcon = profileView.findViewById<ImageView>(com.google.android.material.R.id.icon) val profileTitle = profileView.findViewById<TextView>(com.google.android.material.R.id.title) profileIcon.setImageResource(R.drawable.bottom_bar_profile_selector) profileTitle.setTextColor(ContextCompat.getColorStateList(this, R.color.tab_profile_color_selector)) // 同理处理其他Tab(比如"日志"、"治疗"等)
为什么之前的方法不生效?
BottomNavigationView内部会维护一个统一的样式控制器,默认会忽略单个MenuItem上设置的文字颜色配置,只认全局的itemTextColor。通过手动找到每个Tab的内部子View,我们可以绕过这个全局控制,为每个Tab单独设置样式。
注意事项
- 确保Selector里使用的是
state_checked而不是state_selected,因为BottomNavigationView的选中状态是基于checked属性的。 - 使用
com.google.android.material.R.id.icon和com.google.android.material.R.id.title这两个内部ID来获取子View,不要用自定义ID,避免版本兼容问题。
内容的提问来源于stack exchange,提问作者Itoun
相关产品推荐
相关产品推荐

