Android应用:使用AppCompat库时Popup Menu图标不显示求助
解决AppCompat菜单图标不显示的问题
嘿,我之前也踩过这个坑!新版AppCompat库默认会隐藏溢出菜单里的图标,不过咱们可以通过几个方法让图标显示在文字旁边,下面是具体方案:
方案1:针对顶部工具栏的可见菜单项(非溢出)
如果你的菜单项是直接显示在Toolbar上的(不是折叠到溢出菜单里),直接在菜单XML里配置即可:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/menu_item_example" android:icon="@drawable/ic_example" android:title="示例菜单" app:showAsAction="always|withText" /> <!-- 强制显示图标+文字 --> </menu>
这里的app:showAsAction="always|withText"会让图标和文字一起显示在Toolbar上,注意要用app:命名空间而不是android:,因为这是AppCompat的兼容属性。
方案2:让溢出菜单里的图标显示出来
如果你的菜单项是在溢出菜单(右上角三个点展开的菜单)里,AppCompat默认会隐藏图标,这时候需要通过代码来强制开启:
方法A:使用反射(简单直接)
在你的Activity的onCreateOptionsMenu方法里添加这段代码:
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.your_menu, menu); // 强制显示溢出菜单的图标 if (menu != null) { if (menu.getClass().getSimpleName().equals("MenuBuilder")) { try { Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE); method.setAccessible(true); method.invoke(menu, true); } catch (Exception e) { e.printStackTrace(); } } } return super.onCreateOptionsMenu(menu); }
这段代码通过反射调用MenuBuilder的私有方法,让溢出菜单里的图标可见。
方法B:自定义Toolbar的MenuInflater(更优雅,无反射)
创建一个自定义的MenuInflater,重写相关方法来保留图标:
public class CustomMenuInflater extends MenuInflater { public CustomMenuInflater(Context context) { super(context); } @Override public void inflate(int menuRes, Menu menu) { super.inflate(menuRes, menu); if (menu instanceof MenuBuilder) { ((MenuBuilder) menu).setOptionalIconsVisible(true); } } }
然后在Activity里使用这个自定义的MenuInflater:
@Override public boolean onCreateOptionsMenu(Menu menu) { new CustomMenuInflater(this).inflate(R.menu.your_menu, menu); return super.onCreateOptionsMenu(menu); }
这个方法不需要反射,直接调用MenuBuilder的公开方法(新版AppCompat里这个方法是稳定可用的)。
额外注意事项
- 确保你的图标资源是符合Toolbar尺寸的(一般24dp左右),避免图标显示模糊或异常;
- 确保你的Activity主题继承自
Theme.MaterialComponents.Light.NoActionBar或Theme.AppCompat.Light.NoActionBar这类AppCompat兼容主题,避免样式冲突; - 测试前记得重启APP,有时候主题缓存会导致修改不立即生效。
你可以根据自己的需求选择上面的方案,亲测有效哦!
内容的提问来源于stack exchange,提问作者Priyanka




