Android中Toolbar菜单iconTint不随主题切换变色的原因排查
问题场景
- 已定义菜单并关联到MaterialToolbar
iconBackground颜色在浅色、深色主题下分别配置了不同值- 异常现象:Toolbar的navigationIcon能正常随主题切换颜色,但菜单中的图标始终显示白色
菜单布局(menu_main_top.xml)
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_search" android:icon="@drawable/search" android:iconTint="@color/iconBackground" app:actionViewClass="androidx.appcompat.widget.SearchView" app:showAsAction="ifRoom|collapseActionView" /> <item android:id="@+id/menu_info_bar" android:icon="@drawable/search_barcod" android:iconTint="@color/iconBackground" app:showAsAction="always" /> <item android:id="@+id/menu_filter_list" android:icon="@drawable/select_auction" android:iconTint="@color/iconBackground" app:showAsAction="always" /> </menu>
Toolbar布局
<?xml version="1.0" encoding="utf-8"?> <com.google.android.material.appbar.MaterialToolbar android:id="@+id/topAppBar" style="@style/Widget.MaterialComponents.Toolbar.Primary" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/background" android:visibility="visible" app:menu="@menu/menu_main_top" app:navigationIcon="@drawable/logo" app:navigationIconTint="@color/iconBackground" app:title="@string/app_name" />
主题颜色配置
- 浅色主题(res/values/colors.xml):
<color name="iconBackground">#FFFFFF</color>
- 深色主题(res/values-night/colors.xml):
<color name="iconBackground">#292929</color>
问题原因
菜单item中使用了android:iconTint属性,而MaterialToolbar属于Material Components库,它对菜单图标的渲染逻辑优先遵循Material主题规则,android:iconTint无法很好地适配主题切换机制。另外,菜单的LayoutInflater在加载时可能没有正确关联夜间模式的上下文,导致颜色值不会动态更新。
解决方案
方案1:替换为Material命名空间的tint属性
把菜单item里的android:iconTint改成app:iconTint,MaterialToolbar对自身命名空间的属性支持更好,能正确跟随主题切换:
<item android:id="@+id/menu_search" android:icon="@drawable/search" app:iconTint="@color/iconBackground" app:actionViewClass="androidx.appcompat.widget.SearchView" app:showAsAction="ifRoom|collapseActionView" />
方案2:通过主题统一配置(推荐)
在主题中定义菜单图标的颜色属性,无需逐个item设置,自动适配主题:
- 在
res/values/styles.xml的主题中添加:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <!-- 其他已有属性 --> <item name="actionMenuIconColor">@color/iconBackground</item> </style>
- 移除菜单item中的所有
iconTint属性,让主题统一控制颜色。
方案3:代码动态设置
如果上述方案不生效,可以在代码里手动为菜单图标设置tint:
override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main_top, menu) val tintColor = ContextCompat.getColor(this, R.color.iconBackground) for (i in 0 until menu.size()) { menu.getItem(i).icon?.setTint(tintColor) } return true }
内容的提问来源于stack exchange,提问作者Иван Жуков
相关产品推荐
相关产品推荐

