具有app:showAsAction属性的项目未显示

33

我不理解为什么代码出错并且不兼容(AndroidStudio告诉我应该使用appcompat库中的app:showAsAction)

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/action_search"
      android:title="@string/action_search"
      android:icon="@drawable/search"
      android:showAsAction="always" />
</menu>

工作得很完美,但是像这样的适当和兼容的版本

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

我的图标完全没有显示。

我在三星GT P5210 (Android v. 4.4.2)和Nexus 7 (4.4.4)上进行测试。


你能否提供你在Fragment/Activity中使用的代码? - Siebe
只是: public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } (注意:这是Java代码,不是普通文本。) - ITurchenko
3个回答

56

当您想使用操作栏时,您应始终检查以下内容:

1)扩展ActionBarActivity而不是Activity

public class MainMenu extends ActionBarActivity{

2)在清单文件中选择正确的样式。

清单文件

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >

样式

    <style name="AppTheme"
    parent="Theme.AppCompat.Light.DarkActionBar">
    </style>

3) 选择showAsAction正确标题

  <menu xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:**yourapp**="http://schemas.android.com/apk/res-auto" >
  <item android:id="@+id/action_search"
      android:icon="@drawable/ic_action_search"
      android:title="@string/action_search"
      **yourapp**:showAsAction="ifRoom"  />
    ...
  </menu>

这是大多数人犯错的地方

4) 在Activity中定义您的菜单(Menu)

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu items for use in the action bar
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
}
如果您完成以下所有步骤,则操作栏应该正常工作。然后,您应该为每个位置添加onClickListener...

2
非常感谢您详细的回答。在我的项目中,父主题错误(android:Theme.Holo.Light而不是Theme.AppCompat.Light),并且Activity扩展了基本的Avtivity(而不是ActionBarActivity)。现在它可以正常工作了。 - ITurchenko
从正确的父类、清单(manifest)、样式(style)到菜单设置,带有完整步骤的最佳答案。我建议遇到类似问题的人只需按照步骤一步一步来。 - Lawrence Teo
1
很好的答案。然而,我更倾向于使用@Override public boolean onOptionsItemSelected(MenuItem item)方法,而不是为每个项目使用OnClickListener,如此处所述:http://developer.android.com/guide/topics/ui/menus.html - Zapnologica
1
但是我不明白要在 yourapp 的位置放什么... 你能帮忙吗? - Varun Bhatia
@VarunBhatia 它可以是任何东西。它可以是 xmlns:house="http://schemas.android.com/apk/res-auto" 然后 house:showAsAction="ifRoom" - marduc812

16

我重新阅读了你的问题,发现你的问题恰恰相反(但我的旧回答中有些部分仍然适用于你的问题),因此这是更新后的答案:

更新:

你在gradle文件中导入了appcompat库,但似乎只支持API Level 11或14以上的设备?如果是这种情况,lint检查看到你通过gradle导入了appcompat库,并认为你应该使用ActionBarActivity,因为你导入了该库。这就是为什么会出错。但是由于你的android:showAsAction属性正在工作,你正在使用原生的Activity和正确的本机属性调用,即使lint检查说它是错误的。因此,如果你想消除lint错误,你必须从gradle文件中删除appcompat库,可能还要将你的活动主题更改为本地Holo Light主题,因为你当前的主题可能依赖于appcompat主题。

关于为什么在app命名空间下不起作用的答案,在本机或库代码中处理XML属性加载,已在旧的回答中解决。

旧的回答

如果你正在使用来自支持库的ActionBarActivity以达到低于API级别11的设备,主要问题在于ActionBarActivity重新创建了一些本地Android XML属性,例如android:showAsAction,并将其定义在自己的范围内,你可通过以下方式指定:

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

然后可以使用相同属性(此处为showAsAction)在app:命名空间中访问它们。

因此,ActionBarActivity无法看到或访问本机的android:showAsAction属性,因为它只在app命名空间中查找它,而不是在android命名空间中查找它。

如果要使用本机属性,则必须使用具有Holo主题的本机Activity,它仅支持API级别11及以上。


我发现这非常有帮助,特别是关于查看gradle文件并删除appcompat条目的部分。谢谢! - midiwriter
如果我在浪费几个小时自己解决问题之前读了你的新答案就好了...但是得到一些确认仍然很好! - hubeir

5

addthis:

yourapp:showAsAction="ifRoom"

或者

android:showAsAction

例如:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
    <item android:id="@+id/action_search"
          android:icon="@drawable/ic_action_search"
          android:title="@string/action_search"
          yourapp:showAsAction="ifRoom"  />

</menu>

在Activity中:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu items for use in the action bar
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle presses on the action bar items
    switch (item.getItemId()) {
        case R.id.action_search:
            openSearch();
            return true;
        case R.id.action_compose:
            composeMessage();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

并阅读更多相关信息,请点击此处


xmlns:[yourapp]="" rel = "nofollow noreferrer">http://schemas.android.com/apk/res-auto"> 和 [yourapp]:showAsAction="always" - MilanNz
请问您能否具体描述一下在 [yourapp] 位置应该填写什么?是随意的标签吗?在 AndroidManifest 中没有找到任何关于应用名的引用。 - ITurchenko
在所有地方将 [yourapp] 替换为您的应用程序名称或任何您想要的命名空间。 - MilanNz

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