Android 4.3 菜单项 showAsAction="always" 被忽略

Posted

技术标签:

【中文标题】Android 4.3 菜单项 showAsAction="always" 被忽略【英文标题】:Android 4.3 menu item showAsAction="always" ignored 【发布时间】:2013-07-28 15:38:15 【问题描述】:

我正在使用从 android 4.3(API 级别 18)开始提供的新 v7 appcompat 库。

无论在 showAsAction 中为菜单项指定了什么,它都不会显示 - 它总是创建溢出菜单图标,甚至将单个菜单项放在菜单下。

尝试向这样的活动添加菜单:

@Override
public boolean onCreateOptionsMenu(Menu menu) 
    getMenuInflater().inflate(R.menu.menu_sizes, menu);
    return true;

这是我的菜单 xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

这是新的支持库 v7 的错误,还是只是代码有问题? 我之前已经多次使用 ActionBarSherlock 的类似代码。

【问题讨论】:

仅供参考 - “..."always" 不建议使用;最好使用 "ifRoom" 并让操作系统决定。” 【参考方案1】:

您可能缺少必需的命名空间:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:[yourapp]="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        [yourapp]:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

[yourapp] 替换为您的应用名称或您心中想要的任何命名空间。

其他值得检查的事情:

查看您的活动课程是否扩展ActionBarActivity

检查问题是否仍然存在。


Android 参考文档:Adding Action Buttons。以下是相关文字:

如果您的应用使用支持库以兼容低至 Android 2.1 的版本,则 showAsAction 属性在 android: 命名空间中不可用。相反,此属性由支持库提供,您必须定义自己的 XML 命名空间并将该命名空间用作属性前缀。 (自定义 XML 命名空间应基于您的应用名称,但它可以是您想要的任何名称,并且只能在您声明它的文件范围内访问。)

【讨论】:

这也是我发现的。谢谢 - 绝对接受。但 showAsAction 应该使用该自定义命名空间。 'yourapp' 在 String.xml 中的意思是 yourapp 对吗? 有人能解释一下为什么会这样吗?为什么需要扩展自定义命名空间?有点困惑。 @dineth appcompat 用作库项目。这意味着它的所有资源(字符串、drawable、属性...)都在您的应用程序命名空间而不是 android 命名空间中声明。由于showAsAction属性在android-7中不存在,你必须使用你的应用命名空间 每个人都说“自定义命名空间”或“与您的应用匹配的命名空间”。但在每个示例中,命名空间始终为 http://schemas.android.com/apk/res-auto。这不是自定义的,也不是与您的应用匹配的。这是文档中的实际命名空间。我认为每个人的意思都是自定义的前缀,它实际上可以是你想要的任何东西。这是真的吗?【参考方案2】:

自己想通​​了。使用支持库 v7 时,showAsAction 应该位于这样的自定义命名空间下:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:balloonberry="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        balloonberry:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

【讨论】:

'balloonberry' 在 String.xml 中的意思是 "balloonberry" 对吗? @LOG_TAG - 不,它应该就像上面输入的那样。这不是一个字符串,而是一个命名空间。 ohhh support v7 errr... 支持 v4 没问题 感谢 Mcingwe 的解释【参考方案3】:

还要确保在 ActionBarActivity.onCreateOptionsMenu() 方法中使用正确的充气器。

正确的解决方案:

MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_example, menu);

不正确的解决方案:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);

【讨论】:

我已经通过了上述所有答案和***上的另一个答案,但我唯一缺少的是你的答案——getMenuInflater()。感谢分享。 非常感谢这个。我将我所有的 100 多个菜单都转换为使用自定义命名空间,但 1 个臭屏幕仍然无法正常工作……结果发现 1 个活动正在使用“new MenuInflater”而不是 getMenuInflater()。非常感谢! 这很重要。我正在使用 menuInflater 创建(2 方式)。谢谢 谢谢你,真的帮助了我。顺便说一句,我为此解决方案为 Kotlin 用户添加了其他答案,您可以在下面查看。【参考方案4】:

对于片段

具有自定义命名空间的菜单将阻止 showAsAction 显示。

为 showAsAction 使用“android:”前缀会起作用,即使 Android Studio 会提醒您应该使用自定义命名空间。

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_add_checkin"
          android:title="Add Checkin"
          android:orderInCategory="10"
          android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add"/>
</menu>

这是使用 Android SDK 22 和支持 v4 片段,以防万一。

【讨论】:

这是解决我的问题的唯一方法(尽管它显示了此错误)。谢谢! 您可以使用 中的 tools:ignore="AppCompatResource" 来抑制 XML 布局中的错误/警告。此处的文档:tools.android.com/tips/lint/suppressing-lint-warnings 您的回答和 Anton Kizema 的回答对我来说是正确的解决方案。也感谢您的提示tools:ignore【参考方案5】:

遇到了同样的问题,但在 Android 5 上。我有 3 个项目,但操作系统忽略了我的属性“总是”并且只显示了 2 个项目。这是我的解决方案:

  @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
    Log.d(TAG, "onCreateOptionsMenu()");
    inflater.inflate(R.menu.your_menu, menu);
    for (int j = 0; j < menu.size(); j++) 
        MenuItem item = menu.getItem(j);
        Log.d(TAG, "set flag for " + item.getTitle());
        item.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
    

【讨论】:

setShowAsActionFlags() 需要 API 14,但这对我来说仍然是最好的解决方案。【参考方案6】:

还要确保您拥有正确的命名空间路径。如果错误,它不会给您错误消息。

我有

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:myapp="http://schemas.android.com/res-auto">

而不是

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:myapp="http://schemas.android.com/apk/res-auto">

我只知道它不起作用。不知道我是如何设法忘记路径的 /apk 部分的,但它发生了。没有错误消息,只是一个难以追踪的错误。

【讨论】:

【参考方案7】:

就我而言,我必须从我的应用的 build.gradle compile 'com.android.support:appcompat-v7:21.0.3' 中删除。

注意:我的 min sdk = 14,android studio 创建的项目插入了我不必要的依赖。

替换后你可以写 android:showAsAction="always"

【讨论】:

谢谢它解决了我!在大多数情况下,这可能是最好的解决方案,因为没有必要支持 4.0 之前的 Android 版本。 你的答案和贝克的答案对我来说是正确的解决方案。【参考方案8】:

这可能不是你的情况,但我使用的是

new MenuInflater(this).inflate(R.menu.my_menu, menu);

改成

getMenuInflater().inflate(R.menu.my_menu, menu);

解决了问题!

【讨论】:

【参考方案9】:
<?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/back"
        android:icon="@drawable/back"
        app:showAsAction="always"
        android:title="@string/back"/>
    <item
        android:id="@id/save"
        android:icon="@drawable/le_top_btn_icon_add"
        app:showAsAction="ifRoom"
        android:title="@string/save"/>
</menu>

不工作, 与 supportLibraryVersion = '25.1.0' compileSdkVersion = 25

见“警告”

应该将 app:showAsAction 与 appcompat 库一起使用 xmlns:app="http://schemas.android.com/apk/res-auto" 少... (Ctrl+F1)

在使用 appcompat 库时,菜单资源应参考 app: 命名空间中的 showAsAction, 不是 android: 命名空间。

同样,当不使用 appcompat 库时, 你应该使用 android:showAsAction 属性。

我认为警告可以忽略。

【讨论】:

【参考方案10】:

将这样的自定义命名空间添加到 showAsAction 和 actionViewClass:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
    android:title="@string/search"
    android:icon="@drawable/ic_search"
    app:showAsAction="collapseActionView|ifRoom"
    app:actionViewClass="android.widget.SearchView" />

【讨论】:

【参考方案11】:

我已经通过替换解决了

android:showAsAction="ifRoom"

app:showAsAction="ifRoom"

也就是menuitme xml的样子,

<item android:id="@+id/action_refresh"
      android:title="Refresh"
      android:icon="@drawable/refresh2"
      app:showAsAction="ifRoom" />

【讨论】:

【参考方案12】:

最简单的方法是 通过添加修改您的代码

xmlns:app="http://schemas.android.com/apk/res-auto"

并更改此代码

android:showAsAction="always"

app:showAsAction="always"

最后

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        app:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

【讨论】:

【参考方案13】:

除了@petrnohejl 的回答之外,在 Kotlin 中,您可以直接使用这一行,而无需先对其进行初始化。

override fun onCreateOptionsMenu(menu: Menu?): Boolean 
        menuInflater.inflate(R.menu.options_menu, menu)
        return true
    

在我的例子中,菜单项只是忽略了我的 app:showAsAction="always" 或 "ifRoom",这真的让我烦恼了好几个小时。然后,在 *** 中搜索后,我意识到我没有使用正确的 MenuInflater。

【讨论】:

以上是关于Android 4.3 菜单项 showAsAction="always" 被忽略的主要内容,如果未能解决你的问题,请参考以下文章

Android中app:showASAction的值及含义

Android UI常用组件

为啥工具栏不接受菜单的 showAsAction = "always" 属性

如何检测SearchView是否已扩展?

“在包 'android' 中找不到属性 'showAsAction' 的资源标识符”

谈谈-showAsAction