Android中Toolbar或ActionBar菜单不显示icon的解决方案

在Android开发中,遇到Toolbar或ActionBar的菜单不显示icon的问题。通常,Google设计下,弹出的更多选项不会显示icon。本文提供两种解决方案:一是通过反射机制在MenuBuilder类中设置属性;二是修改菜单布局,变相实现显示icon。这两种方法都可以在不显示icon的情况下进行修复。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于Android开发中menu的选项菜单不显示icon的问题处理

在Google的设计理念中,使用频次高的菜单项,可以放在ToolBar或ActionBar中,显示图标或文字。而在弹出的更多选项中,并不会显示出icon,尽管我们已经在menu的layout中配置了android:icon属性。

一、普通的menu布局
<?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/location_menu"
			android:icon="@drawable/location"
			android:title="@string/str_location"
			app:showAsAction="always" />
	<item
			android:id="@+id/map_menu"
			android:icon="@drawable/earth"
			android:title="@string/str_map"
			app:showAsAction="always|withText" />
	<item
			android:id="@+id/share_menu"
			android:icon="@drawable/share"
			android:title="@string/str_share"
			app:showAsAction="withText" />
	<item
			android:id="@+id/feedback_menu"
			android:icon="@drawable/feedback"
			android:title="@string/str_feedback" />
	<item
			android:id="@+id/about_menu"
			android:icon="@drawable/about"
			android:title="@string/str_about" />
</menu>

如图效果common在三个点的下弹item中是不显示icon图标的,虽然布局中已经有了。原因上面说过了,国内开发习惯的问题,都希望显示icon,所以有以下两种解决方式

二、解决方案
  • 通过反射机制,在onCreateOptionsMenu中,反射MenuBuilder的属性设置

    try {
    			Class<?> clazz = Class . forName ("com.android.internal.view.menu.MenuBuilder");
    			Method m = clazz . getDeclaredMethod ("setOptionalIconsVisible", boolean.class);
    			m.setAccessible(true);
    			m.invoke(menu, true);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    

    **注意:**这里填写的Menu Builder包名,要和你使用的保持一致。如果使用了androidx包,则这里替换为androidx.appcompat.view.menu.MenuBuilder

  • Kotlin的反射方式,类似与Java,将以下代码放在onCreateOptionsMenu的函数中就好

    //反射,设置icon
    		val clazz = Class.forName("androidx.appcompat.view.menu.MenuBuilder")
    		val m = clazz.getDeclaredMethod("setOptionalIconsVisible", Boolean::class.java)
    		m.isAccessible = true
    		m.invoke(menu, true)
    
  • 变相使用menu group的方式,不用代码反射,修改menu的布局

    <?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/location_menu"
    			android:icon="@drawable/location"
    			android:title="@string/str_location"
    			app:showAsAction="always" />
    	<item
    			android:id="@+id/map_menu"
    			android:icon="@drawable/earth"
    			android:title="@string/str_map"
    			app:showAsAction="always|withText" />
    	<!--下面的icon,替换成自定义的 三个点 图标,或者其他图标-->
    	<item android:title="" app:showAsAction="always"
    	      android:icon="@drawable/ic_menu_more">
    		<menu>
    			<item
    					android:id="@+id/share_menu"
    					android:icon="@drawable/share"
    					android:title="@string/str_share"
    					app:showAsAction="withText" />
    			<item
    					android:id="@+id/feedback_menu"
    					android:icon="@drawable/feedback"
    					android:title="@string/str_feedback" />
    			<item
    					android:id="@+id/about_menu"
    					android:icon="@drawable/about"
    					android:title="@string/str_about" />
    		</menu>
    	</item>
    </menu>
    

效果图icon

声明:以上两种方案,都不是个人原创,也不记得在Google上搜索的那个网址的了,总之,在此感谢伟大的开源精神!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值