菜单中的图标在安卓系统中无法显示

44

我希望在我的项目中添加菜单处理程序。我也阅读了 http://developer.android.com/guide/topics/ui/menus.html,它很简单,但图标没有显示出来。我非常困惑。我甚至已经以编程方式添加了一个菜单项。

我的代码是:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(0, 0, 0, "Quit").setIcon(R.drawable.ic_launcher);
    getMenuInflater().inflate(R.layout.menu, menu);
    return true;
}

并且在xml中:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Single menu item 
         Set id, icon and Title for each menu item 
    -->
    <item android:id="@+id/menu_bookmark" 
          android:icon="@drawable/update"
          android:title="@string/Update" />

</menu>

您的设备运行哪个Android版本? - Hardik
4.1.2,但我运行了http://www.androidhive.info/2011/09/how-to-create-android-menus/,它正常工作。 - Shayan Pourvatan
2
这绝对是 Android 中最令人沮丧的问题之一。我不知道为什么它不起作用。他们的文档做的和你一样,但它就是不起作用。 - Michael Yaworski
1
在 Androidhive 的演示中,它展示了低于 3.0 版本的内容。如果您在 3.0 以下版本(如 2.2、2.3 等)中运行程序,它将可以正常工作。 - Hardik
2
http://developer.android.com/reference/android/view/Menu.html 表示不支持图标或某些内容。 - Michael Yaworski
可能是如何在ActionBar的溢出菜单中显示图标的重复问题。 - Fattie
11个回答

48

经过长时间尝试,我找到了以下解决方案,它可能会帮助其他人节省时间。基本上,这个解决方案是由"lbarbosa"提供的,我要真诚地感谢他。

根据之前的答案尝试了这个方法,对于较新版本的支持库(25.1)至少可以正常工作:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);

    if(menu instanceof MenuBuilder){
        MenuBuilder m = (MenuBuilder) menu;
        m.setOptionalIconsVisible(true);
    }

    return true;
}

4
唯一真正可行的解决方案,但你需要添加@SuppressLint("RestrictedApi") - Yahya
1
认真的各位,唯一真正有效的解决方案。是的,别忘了在方法public boolean onCreateOptionsMenu(Menu menu)上加上@SuppressLint("RestrictedApi")。 - Yo Apps
太棒了!兄弟,你真的帮我节省了时间。 - Orlov Const
1
现在,至少对于Android Kotlin而言,该方法的名称似乎是setForceShowIcon()。 - Juan Alonso

37

如果您正在运行 Android 3.0+ 上的代码,菜单中的图标不会显示,这是 Google 的设计决策。

您可以在Android 开发者博客中详细了解此信息。


但我运行了http://www.androidhive.info/2011/09/how-to-create-android-menus/,它可以正常工作。 - Shayan Pourvatan
当您的活动无法工作时,是否扩展了“ActionBarActivity”? - Szymon
两个版本的目标API是什么?一样吗?您是否针对相同的API级别构建? - Szymon
1
不对,我的 API 版本是 4.1,而我使用的示例是较低版本的 3。 - Shayan Pourvatan
1
默认情况下不显示它们,但现在可以显示。请参见Pranob的答案。 - Juan Alonso

28

无论系统做出了什么设计选择,您都可以通过在此问题的获赞最高答案中提供的解决方案绕过此问题。

以下是完整代码。已测试可在android.support.v7.app.ActionBarActivity上工作。

@Override
public boolean onMenuOpened(int featureId, Menu menu)
{
    if(featureId == Window.FEATURE_ACTION_BAR && menu != null){
        if(menu.getClass().getSimpleName().equals("MenuBuilder")){
            try{
                Method m = menu.getClass().getDeclaredMethod(
                    "setOptionalIconsVisible", Boolean.TYPE);
                m.setAccessible(true);
                m.invoke(menu, true);
            }
            catch(NoSuchMethodException e){
                Log.e(TAG, "onMenuOpened", e);
            }
            catch(Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    return super.onMenuOpened(featureId, menu);
}

1
这个对我来说几乎起作用了。出于我不理解的原因,featureId值为0。我用以下语句替换了第一个if语句: “if(featureId == Window.FEATURE_OPTIONS_PANEL && menu!= null){” 然后它就起作用了。虽然,我不确定“FEATURE_OPTION_PANEL”是我应用程序获取的0的正确含义。 - Steve Gelman
3
由于我的featureId是108而不是8,我能否将featureId == Window.FEATURE_ACTION_BAR替换为(featureId & Window.FEATURE_ACTION_BAR) == Window.FEATURE_ACTION_BAR - Ninja
1
我对单个&符号的用法不太理解,但无论如何,你可以尝试在任何活动中覆盖onMenuOpened方法,即使没有检查该功能是否存在(当然,你仍然可以检查menu!=null),看看在你的情况下跨设备/SDK的行为是否可取。 - leRobot
谢谢!我使用了你的代码,但是将featureId == Window.FEATURE_ACTION_BAR替换为(featureId & Window.FEATURE_ACTION_BAR) == Window.FEATURE_ACTION_BAR。@leRobot: https://dev59.com/7W445IYBdhLWcg3wpb4P 解释了单个和符号在整数上的工作原理和原因,一旦你阅读了那篇文章,你会同意这里的用法非常聪明 :) - Igor
啊,谢谢。在我看来,这是Java的一种较低级的表示法,但是逻辑似乎是正确的。 - leRobot
显示剩余3条评论

19

虽然是老问题,但仍希望能有所帮助。

请使用以下代码:

<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_share"
    android:title="Share"
    app:showAsAction="always"
    android:icon="@drawable/share" /></menu>

请注意,我使用了app:showAsAction而不是android:showAsAction


这是我需要做的。谢谢。 - hellaandrew

6
您可以在item元素中添加属性android:showAsAction="always"到您的XML文件中。这将会在您的操作栏中以图标的形式显示相关菜单选项。请注意,它将代替菜单中的文本。如需进一步了解,请参阅此处的android:showAsAction部分:http://developer.android.com/guide/topics/resources/menu-resource.html

4
/* menu code */   
    <?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/one" android:title="one"
            android:icon="@mipmap/ic_launcher" app:showAsAction="always" />
        <item android:id="@+id/two" android:title="two"
            android:icon="@mipmap/ic_launcher" app:showAsAction="always" />
        <item android:id="@+id/three" android:title="three"
            android:icon="@mipmap/ic_launcher"  />
    </menu>
   /* Java code */

    @SuppressLint("RestrictedApi")
        @Override
        public boolean onCreateOptionsMenu(Menu menu)
        {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.mymenu,menu);
            if(menu instanceof MenuBuilder){
                MenuBuilder m = (MenuBuilder) menu;
                m.setOptionalIconsVisible(true);
            }
            return true;
        }

1
忘记所有那些,执行以下步骤。将app:showsAsAction="always"添加到您的项目中。如果您使用android:showsAsAction="always",您将无法得到解决方案。尝试将 app 属性添加到您的项目中。

2
这只是使其出现在实际的工具栏上(而不是菜单中)作为操作项。 - Fattie

1
我用以下代码在onCreateOptionsMenu方法中放置了明确的图标。
for (int i = 0; i < menu.size(); i++) { MenuItem item = menu.getItem(i);
        if (item.getItemId() == R.id.print) {
            item.setIcon(getDrawable(R.drawable.print));

} }


0

在使用android.support.v7.app.AppCompatActivity时,将图标作为输入变得非常困难。您需要实现来自AppCompatActivity类的超级方法onMenuOpen。此检查后,如果菜单不为空,则传递Method类并使用boolean值将setOptionalIconsVisible设置为true。

@Override
public boolean onMenuOpened(int featureId, Menu menu) {

    if(menu != null){
        if(menu.getClass().getSimpleName().equals("MenuBuilder")){
            try{
                Method m = menu.getClass().getDeclaredMethod(
                        "setOptionalIconsVisible", Boolean.TYPE);
                m.setAccessible(true);
                m.invoke(menu, true);
            }
            catch(NoSuchMethodException e){
                Log.e("MAIN", "onMenuOpened", e);
            }
            catch(Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    return super.onMenuOpened(featureId, menu);
}

0

只需在menu.xml中的item标签内添加此属性即可

app:showAsAction="always

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接