Item de menu Android 4.3 showAsAction = “sempre” ignorado

116

Estou usando a nova biblioteca appcompat v7 disponível a partir do Android 4.3 (API de nível 18).

Independentemente do que é especificado em showAsAction para um item de menu, ele não é mostrado - ele sempre cria o ícone de menu flutuante e coloca até mesmo um único item de menu sob o menu.

Tentando adicionar menu a uma atividade como esta:

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

E aqui está meu menu 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>

É um bug da nova biblioteca de suporte v7 ou apenas algo errado com o código? Eu usei o código semelhante com ActionBarSherlock muitas vezes antes.

Mcingwe
fonte
2
Para fins informativos - "... "always"não é recomendado; é melhor usar "ifRoom"e deixar o sistema operacional decidir."
ChiefTwoPencils

Respostas:

313

Provavelmente está faltando o namespace obrigatório:

<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>

Substitua [yourapp]pelo nome do aplicativo ou qualquer namespace que você deseja em todos os lugares.

Outras coisas que valem a pena verificar:

  • Veja se sua aula de atividade se estende ActionBarActivity

Verifique se o problema persiste.


Documentação de referência do Android: Adicionando botões de ação . Aqui está o texto relevante:

Se o seu aplicativo estiver usando a Biblioteca de Suporte para compatibilidade com versões tão baixas quanto Android 2.1, o atributo showAsAction não está disponível no android: namespace. Em vez disso, esse atributo é fornecido pela Biblioteca de Suporte e você deve definir seu próprio namespace XML e usar esse namespace como o prefixo do atributo. (Um namespace XML personalizado deve ser baseado no nome do seu aplicativo, mas pode ser qualquer nome que você quiser e só pode ser acessado dentro do escopo do arquivo em que você o declara.)

Nikola Despotoski
fonte
2
Foi o que descobri também. Obrigado - definitivamente aceito. Mas o showAsAction deve usar esse namespace personalizado.
Mcingwe
5
'yourapp' significa em String.xml <string name = "app_name"> seu aplicativo </string> certo?
LOG_TAG
4
Alguém pode explicar POR QUE isso funciona? Por que é necessário estender um namespace personalizado? Um pouco confuso.
jantar em
8
@dineth appcompat é usado como um projeto de biblioteca. Isso significa que todos os seus recursos (strings, drawable, atributos ...) são declarados no namespace do seu aplicativo em vez do namespace android. Como o showAsActionatributo não existia no android-7, você deve usar o namespace do seu aplicativo
nicopico
22
Todo mundo diz "namespace personalizado" ou "um namespace que corresponda ao seu aplicativo". Mas o namespace está sempre http://schemas.android.com/apk/res-autoem todos os exemplos. Não é personalizado ou que corresponda ao seu aplicativo. Esse é o namespace real da documentação. Acho que todo mundo significa um prefixo personalizado e pode ser o que você quiser. Isso é verdade?
Andrew Arnott
52

Descobri sozinho. Com a biblioteca de suporte v7, showAsAction deve estar em um namespace personalizado como este:

<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
fonte
1
'balloonberry' significa em String.xml "<string name =" app_name "> balloonberry </string>" certo?
LOG_TAG
5
@LOG_TAG - não, deve ser apenas como inserido acima. Isso não é uma string, mas um namespace.
BeccaP
ohhh suporte v7 errr ... está ok no suporte v4
Yasitha Waduge
Obrigado pela explicação Mcingwe
Sachidananda Naik
32

Certifique-se também de usar o inflador correto no método ActionBarActivity.onCreateOptionsMenu ().

Solução correta:

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

Solução incorreta:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);
Petrnohejl
fonte
1
Passei em todas as respostas acima e em outras respostas em stackoverflow, mas a única coisa que estava faltando é sua resposta - getMenuInflater (). Obrigado por compartilhar isso.
Amt87
Muito obrigado por este. Converti todos os meus mais de 100 menus para usar um namespace personalizado e 1 tela fedorenta ainda não estava funcionando ... Acontece que 1 atividade estava usando "new MenuInflater" em vez de getMenuInflater (). Muito obrigado!
DiscDev
isto é muito importante. Eu estava usando a criação do menuInflater (2 vias). Obrigado
semana
24

Para Fragmentos

Menus com namespace personalizado impedirão a exibição de showAsAction.

Usar o prefixo "android:" para showAsAction funcionará, embora o Android Studio observe que você deve usar um namespace personalizado.

<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>

Isso está usando Android SDK 22 e fragmentos de suporte v4, caso isso faça alguma diferença.

padeiro
fonte
Essa é a única coisa que resolveu Meu problema (embora esteja mostrando esse erro). Obrigado !
user2630165
3
Você pode suprimir o erro / aviso no layout XML com ferramentas: ignore = "AppCompatResource" em <item>. Documentos aqui: tools.android.com/tips/lint/suppressing-lint-warnings
Baker
Sua resposta e a de Anton Kizema são as soluções certas para mim. E também obrigado pela dica tools:ignore.
hata
16

Tenho o mesmo problema, mas no Android 5. Eu tenho 3 itens, mas o SO ignorou meu atributo "sempre" e mostrou apenas 2 itens. Aqui está minha solução:

  @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
fonte
1
setShowAsActionFlags()requer API 14, mas esta ainda era a melhor solução para mim.
Sr. Bungle
6

Além disso, certifique-se de ter o caminho correto para o namespace. Ele não apresentará uma mensagem de erro se estiver errado.

eu tinha

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

ao invés de

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

Tudo que eu sabia era que não estava funcionando. Não sei como consegui esquecer a parte / apk do caminho, mas aconteceu. Nenhuma mensagem de erro, apenas um bug indescritível para rastrear.

BeccaP
fonte
6

No meu caso, tive que remover da compilação build.gradle do meu aplicativo 'com.android.support:appcompat-v7:21.0.3'.

Aviso : Meu min sdk = 14 e o projeto criado pelo android studio inseriu minha dependência desnecessária.

Após essa substituição, você pode escrever android: showAsAction = "always"

Anton Kizema
fonte
Obrigado, isso me resolveu! Hoje em dia talvez seja a melhor solução na maioria dos casos, porque não é necessário suportar versões do Android anteriores a 4.0.
pinyin_samu de
Sua resposta e a de Baker são as soluções certas para mim.
hata
4

Este pode não ser o seu caso, mas eu estava usando

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

mudando para

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

corrigiu o problema!

Bakhshi
fonte
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>

não funciona, com supportLibraryVersion = '25 .1.0 'compileSdkVersion = 25

veja o "Aviso"

Deve usar app: showAsAction com a biblioteca appcompat com xmlns: app = "http://schemas.android.com/apk/res-auto" menos ... (Ctrl + F1)

Ao usar a biblioteca appcompat, os recursos do menu devem se referir a showAsAction no namespace app:, não ao android: namespace.

Da mesma forma, quando não estiver usando a biblioteca appcompat, você deve usar o atributo android: showAsAction.

Acho que o aviso pode ser ignorado.

Conta
fonte
0

adicione um namespace personalizado como este para showAsAction e 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" />

Amirouche Zeggagh
fonte
0

Eu resolvi isso substituindo

android:showAsAction="ifRoom"

com

app:showAsAction="ifRoom"

Isso é menuitme xml parece,

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

A maneira mais simples é modificar seu código adicionando

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

e mude este código

android:showAsAction="always"

para

app:showAsAction="always"

e finalmente

<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>
Abdulhakim Zeinu
fonte