Android中Toolbar或ActionBar菜单不现实icon的解决方案

关于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上搜索的那个网址的了,总之,在此感谢伟大的开源精神!