Пункт меню Android 4.3 showAsAction = «всегда» игнорируется

116

Я использую новую библиотеку appcompat v7, доступную начиная с Android 4.3 (уровень API 18).

Независимо от того, что указано в 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.

Mcingwe
источник
2
В информационных целях - «... "always"не рекомендуется; лучше использовать, "ifRoom"пусть решает ОС».
ChiefTwoPencils

Ответы:

313

Возможно, вам не хватает необходимого пространства имен:

<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: Добавление кнопок действий . Вот соответствующий текст:

Если ваше приложение использует библиотеку поддержки для совместимости с такими низкими версиями, как Android 2.1, атрибут showAsAction недоступен в пространстве имен android :. Вместо этого этот атрибут предоставляется библиотекой поддержки, и вы должны определить собственное пространство имен XML и использовать это пространство имен в качестве префикса атрибута. (Пользовательское пространство имен XML должно основываться на имени вашего приложения, но это может быть любое имя, которое вы хотите, и оно доступно только в пределах того файла, в котором вы его объявляете.)

Никола Деспотоски
источник
2
Я тоже это выяснил. Спасибо - однозначно принято. Но showAsAction должно использовать это настраиваемое пространство имен.
Mcingwe
5
'yourapp' означает в String.xml <string name = "app_name"> yourapp </string>, верно?
LOG_TAG
4
Может кто-нибудь объяснить, ПОЧЕМУ это работает? Зачем нужно расширять настраиваемое пространство имен? Немного запутался.
Дин
8
@dineth appcompat используется как проект библиотеки. Это означает, что все его ресурсы (строки, возможности рисования, атрибуты ...) объявлены в пространстве имен вашего приложения, а не в пространстве имен android. Поскольку showAsActionатрибут не существует в android-7, вы должны использовать пространство имен своего приложения
nicopico
22
Все говорят «настраиваемое пространство имен» или «пространство имен, соответствующее вашему приложению». Но пространство имен всегда есть http://schemas.android.com/apk/res-autoв каждом примере. Это не индивидуальный вариант и не тот, который соответствует вашему приложению. Это фактическое пространство имен из документации. Я думаю, что каждый имеет в виду собственный префикс , и на самом деле это может быть что угодно. Это правда?
Эндрю Арнотт
52

Разобрался сам. С библиотекой поддержки 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>
Mcingwe
источник
1
"Воздушный шар" означает в String.xml "<string name =" app_name "> bubbleberry </string>", верно?
LOG_TAG
5
@LOG_TAG - нет, он должен быть таким, как указано выше. Это не строка, а пространство имен.
BeccaP
оххх поддержка v7 эррр ... все в порядке с поддержкой v4
Ясита Вадуге
Спасибо за объяснение, Mcingwe
Sachidananda Naik
32

Также убедитесь, что вы используете правильный надувной элемент в методе ActionBarActivity.onCreateOptionsMenu ().

Правильное решение:

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

Неправильное решение:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);
petrnohejl
источник
1
Я прошел все вышеперечисленные ответы и другие ответы на stackoverflow, но единственное, чего мне не хватало, - это ваш ответ - getMenuInflater (). Спасибо, что поделились этим.
Amt87
Большое вам спасибо за это. Я преобразовал все свои 100+ меню, чтобы использовать собственное пространство имен, и 1 вонючий экран все еще не работал ... оказывается, что 1 действие использовало "new MenuInflater" вместо getMenuInflater (). Благодаря тонну!
DiscDev
это очень важно. Я использовал создание menuInflater (2 способа). Спасибо
wtk
24

Для фрагментов

Меню с настраиваемым пространством имен предотвратят отображение showAsAction.

Использование префикса «android:» для showAsAction будет работать, даже если 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, если это имеет значение.

пекарь
источник
Это единственное, что решило мою проблему (хотя и показывает эту ошибку). Спасибо !
user2630165
3
Вы можете подавить ошибку / предупреждение в XML-макете с помощью tools: ignore = "AppCompatResource" внутри <item>. Документы здесь: tools.android.com/tips/lint/suppressing-lint-warnings
Бейкер,
Ваш ответ и ответ Антона Киземы - правильные решения для меня. А также спасибо за подсказку tools:ignore.
hata
16

Возникла та же проблема, но на 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);
    }
}
Lukas
источник
1
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, но это случилось. Никакого сообщения об ошибке, просто неуловимая ошибка, которую нужно отследить.

BeccaP
источник
6

В моем случае мне пришлось удалить из моего приложения build.gradle compile 'com.android.support:appcompat-v7:21.0.3'.

уведомление : мой min sdk = 14, и созданный проект студией Android вставил мою ненужную зависимость.

После этой замены вы можете написать android: showAsAction = "always"

Антон Кизема
источник
Спасибо, это решило меня! В наши дни, возможно, лучшее решение в большинстве случаев, потому что нет необходимости поддерживать версии Android до 4.0.
pinyin_samu
Ваш ответ и ответ Бейкера - правильные решения для меня.
hata
4

Возможно, это не ваш случай, но я использовал

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

меняя это на

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

исправил проблему!

Бакши
источник
0
<?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 ресурсы меню должны ссылаться на showAsAction в пространстве имен app:, а не на пространство имен android :.

Точно так же, когда вы не используете библиотеку appcompat, вы должны использовать атрибут android: showAsAction.

Думаю, на предупреждение можно не обращать внимания.

Билл
источник
0

добавьте собственное пространство имен, подобное этому, для 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" />

Амируш Зегга
источник
0

Я решил это заменой

android:showAsAction="ifRoom"

с участием

app:showAsAction="ifRoom"

Это выглядит как menuitme xml,

<item android:id="@+id/action_refresh"
      android:title="Refresh"
      android:icon="@drawable/refresh2"
      app:showAsAction="ifRoom" />
Харис
источник
0

Самый простой способ - изменить код, добавив

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>
Абдулхаким Зейну
источник