A barra de ação do Android não mostra estouro

90

Eu tenho uma barra de ação em meu aplicativo com 3 itens.

Apenas 2 podem ser exibidos devido a problemas de espaço, então espero que o primeiro seja exibido e o restante seja exibido no estouro. No entanto, na prática, apenas os 2 primeiros itens são mostrados e não há estouro detectável.

Aqui está o código relevante: list_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_insert"
    android:icon="@android:drawable/ic_menu_add"
    android:title="@string/menu_insert" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_call"
    android:icon="@android:drawable/ic_menu_call"
    android:title="@string/menu_call" 
    android:showAsAction="ifRoom|withText"/>
<item android:id="@+id/menu_agenda"
    android:icon="@android:drawable/ic_menu_agenda"
    android:title="@string/menu_agenda" 
    android:showAsAction="ifRoom|withText"/>
</menu>

Activity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater mi = getMenuInflater();
    mi.inflate(R.menu.list_menu, menu);
    return true;
}
Mats Raemen
fonte
120
Se o seu dispositivo tiver um botão de menu, o ícone de estouro não aparecerá. Em qual dispositivo você está?
Reinier
1
o dispositivo virtual que estou testando tem um botão de menu, cliquei nele e o item que faltava apareceu, obrigado!
Mats Raemen
2
@Reinier Estou usando ActionBarSherlock. No Galaxy Ace rodando 2.3, ele é mostrado, no Galaxy SII rodando 4.0 não. Ambos possuem botão de menu HW.
Senhor Smith
2
Eu queria confirmar que isso me deixou perplexo por ter o ícone de estouro em uma compra do Nexus 7, não no Galaxy Note II. O Note tinha um botão de menu. Obrigado!
bsautner
@Reinier por favor me ajude se estou enfrentando o mesmo problema o que devo fazer?
ruptura de

Respostas:

125

Se você quiser mostrar os três pontos, independentemente do botão de menu do dispositivo! então você pode chamar este método em sua classe de aplicativo 'método onCreate-

private void makeActionOverflowMenuShown() {
    //devices with hardware menu button (e.g. Samsung Note) don't show action overflow menu
    try {
        ViewConfiguration config = ViewConfiguration.get(this);
        Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
        if (menuKeyField != null) {
            menuKeyField.setAccessible(true);
            menuKeyField.setBoolean(config, false);
        }
    } catch (Exception e) {
        Log.d(TAG, e.getLocalizedMessage());
    }
}
Atul Kaushik
fonte
32
Este é um hack horrível que quebra a consistência com o resto dos aplicativos na plataforma. Não faça isso.
adamp
19
Este parece o menor de dois males. O comportamento atual é inaceitável.
biorbnA
6
É uma ótima maneira de permitir o estouro, a tecla do menu não deve mais ser tolerada.
Necronet
5
Funciona muito bem! Funciona mesmo se o usuário pressionar o botão de menu de hardware (que é brilhante), embora você ouvirá o efeito de som do menu duas vezes .. alguém sabe como fazê-lo soar apenas uma vez?
Bruce
5
ISTO NÃO É UM HACK. Os desenvolvedores precisam saber o que chamar de hacks, já que não é 2 + 2 no Android. A reflexão está economizando tempo usando mecanismos Java, ou então você estaria passando contextos para suas classes internas 24 horas por dia, 7 dias por semana, ou personalizando AOSP para o infinito. Para mim, essa solução resolve o problema de ter que substituir e incluir toneladas de conteúdo personalizado AOSP E associações privadas vinculadas apenas por causa do que os puristas consideram limpo. Você sabia que não é possível forçar a ativação do FASTSCROLL de forma consistente para listas pequenas? Antes de usar a reflexão, isso exigia que eu copiasse mais de 10 recursos AOSP, para uma edição de UM caractere.
leRobot de
54

Barra de ação

res / menu / menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- Search / will display always -->
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="always"
        android:title="@string/action_search"/>

    <!-- Location Found -->
    <item
        android:id="@+id/action_location_found"
        android:icon="@drawable/ic_action_location_found"
        android:showAsAction="always"
        android:title="@string/action_location_found"/>

    <!-- More -->
    <item
        android:id="@+id/a_More"
        android:icon="@drawable/ic_action_overflow"
        android:showAsAction="always"
        android:title="More">
        <menu>

            <!-- Refresh -->
            <item
                android:id="@+id/action_refresh"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_refresh"/>

            <!-- Help -->
            <item
                android:id="@+id/action_help"
                android:icon="@drawable/ic_action_help"
                android:showAsAction="never"
                android:title="@string/action_help"/>

            <!-- Check updates -->
            <item
                android:id="@+id/action_check_updates"
                android:icon="@drawable/ic_action_refresh"
                android:showAsAction="never"
                android:title="@string/action_check_updates"/>
        </menu>
    </item>

</menu>

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);

        return super.onCreateOptionsMenu(menu);
    }

}

Baixe o conjunto de ícones da barra de ação

Kirit Vaghela
fonte
2
Dê uma olhada no comentário do @Reinier, é verdade "Se seu dispositivo tiver um botão de menu, o ícone de estouro não aparecerá".
Ahmad Dwaik 'Warlock'
Eu testei em um dispositivo que tinha botão de menu e estourava no meu caso. Eu uso android:showAsAction="always"para mais item
Kirit Vaghela
em qual dispositivo você testou? Eu usei um neo v xperia e s #
Ahmad Dwaik 'Warlock'
1
Nota: Seu item que infla seu menu flutuante DEVE mostrarAsAction = "always"
Kirit Vaghela
1
showAsAction não está disponível no namespace android em SDKs mais antigos. Siga este link developer.android.com/training/basics/actionbar/… para superar isso. Depois de adicionar este NS schemas.android.com/apk/res-auto , o truque acima funcionou perfeitamente para mim
chedine
42

Sei que este não é um menu flutuante, mas é semelhante. Ok, isso é simples, mas foi difícil de descobrir.

Primeiro, você precisa de um item de menu que deseja usar como inflador de estouro. Exemplo

<item
        android:id="@+id/a_More"
        android:icon="@drawable/more"
        android:showAsAction="always"
        android:title="More">
        </item>

Depois de ter seu item, adicione um submenu contendo os itens que deseja no menu flutuante. Exemplo:

<item
    android:id="@+id/a_More"
    android:icon="@drawable/more"
    android:showAsAction="always"
    android:title="More">
    <menu>
        <item
            android:id="@+id/aM_Home"
            android:icon="@drawable/home"
            android:title="Home"/>
    </menu>
</item>

Ao clicar, isso aumentará outros itens dentro. Meu aplicativo está usando ActionBarSherlock 4.0, então antes que isso funcione para você, você precisará acessar a "SplitActionBar". (Ainda funcionará na Actionbar padrão do Android)

Veja como: Em seu arquivo AndroidManifest.xml, você precisa adicionar este código na atividade em que precisa do menu flutuante.

android:uiOptions="splitActionBarWhenNarrow"

NOTA: Seu item que infla seu menu flutuante DEVEshowAsAction="always"

Vwola! você tem um menu flutuante! Espero ter ajudado você. :)

LeviRockerSk8er
fonte
3
Boa solução, melhor do que o hack do botão de menu.
ol0
26

Em dispositivos com botões de menu de hardware (Galaxy S3, teimoso como o Samsung é ...) o menu flutuante se comporta como o menu 'tradicional', usando o botão de menu de hardware.

Lukas Batteau
fonte
2
Resposta antiga, no entanto, com a biblioteca de compatibilidade tropeçamos em resultados muito estranhos: 3 dispositivos com botão de hardware, Nota 3 Neo = menu de estouro é mostrado, botão de menu não funciona, Nota 1 = Sem estouro, botão de menu funciona, Galaxy S3, não estouro, o botão do menu não funciona! Isso é loucura.
3c71
5

Quando você diz menu "estouro", você quer dizer os três pontos que aparecem no final para indicar que há mais itens ... ou você quer dizer a barra de ação dividida que aparece na parte inferior para itens de estouro?

Se você se refere à barra de ação dividida, deve adicioná-la ao arquivo de manifesto de sua atividade

android:uiOptions="splitActionBarWhenNarrow"

Por padrão, o menu flutuante de três pontos deve acontecer automaticamente, por isso é difícil dizer qual é o problema com as informações fornecidas acima.

wnafee
fonte
Eu quero dizer os três pontos. Não é por causa dos itens, porque sempre que mudar os itens de ordem, são os 2 primeiros ícones que são mostrados
Mats Raemen
devo fornecer informações extras para poder determinar o problema real?
Mats Raemen
Quais são suas minSdkVersion, targetSdkVersion e a versão que você está testando?
Sparky
5
O seu dispositivo tem botões físicos para menu ou são botões virtuais como o telefone Galaxy Nexus? Acho que os três pontos só aparecerão se o seu telefone não tiver botões físicos.
wnafee
5

Para mostrar sempre o estouro de ação (três pontos) em actionbarcompat:
no arquivo de menu, exemplo:
main.xml

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

    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        app:showAsAction="never"/>
    <item
        android:id="@+id/action_about"
        android:title="@string/action_about"
        app:showAsAction="never"/>

</menu>

e no arquivo de atividade:

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

Funcionou bem para mim.
Testado no Google Nexus S, Samsung S3.

MrSiro
fonte
3

Parece que em dispositivos com um botão de menu, o menu flutuante não é exibido na ActionBar. Além disso, não temos como saber se um dispositivo possui um botão de menu de hardware antes do nível 14 da API (4.0+).

Esta solução adiciona um botão de estouro a um android.support.v7.app.ActionBarque abre o menu de opções padrão no pré-Honeycomb (<3.0) apenas, caso contrário, deixa-o para o sistema. Em qualquer caso, você pode escolher entre alwaysou ifRoompara todas as ações.

Obtenha o ícone de estouro do Action Bar Icon Pack .

Adicionar um menu (omitindo algumas partes não relevantes como títulos, ordem etc.)

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

<item
    android:id="@+id/action_overflow"
    android:orderInCategory="100"
    android:icon="@drawable/ic_action_overflow"
    app:showAsAction="always" />

<item
    android:id="@+id/action_first"
    app:showAsAction="always" />

<item
    android:id="@+id/action_second"
    app:showAsAction="ifRoom" />

</menu>

Remova nossa ação de estouro em 3.0+

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        menu.removeItem(R.id.action_overflow);
    }
    return super.onPrepareOptionsMenu(menu);
}

Finalmente chame Activity.openOptionsMenu()da ação de estouro.

ER não. Você não pode não chamar openOptionsMenu()de um botão de menu ... mas se estiver usando AndroidAnnotations será fácil:

@OptionsItem
void action_overflow() {
    openOptionsMenuDeferred();
}

@UiThread
void openOptionsMenuDeferred() {
    openOptionsMenu();
}

Se não, você deveria fazer algo assim, suponho

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == id.action_overflow) {
        openOptionsMenuDeferred();
        return true;
    }
}

private Handler handler = new Handler(Looper.getMainLooper());
public void openOptionsMenuDeferred() {
    handler.post(new Runnable() {
        @Override
        public void run() {
            openOptionsMenu();
        }
    }
    );
}
IlDan
fonte
2

Tente alterar o tema do aplicativo de Theme.AppCompat.Light.DarkActionBar para Theme.AppCompat.Light

Sagar Devanga
fonte
2

Coloque xmlns:your_app_name="http://schemas.android.com/apk/res-auto"dentro da tag de menu e, em vez disso, android:showAsAction="always"useyour_app_name:showAsAction="always"

por exemplo

<item
    android:id="@+id/action_search"
    android:icon="@drawable/icon_search"
    android:title="@string/search"
    your_app_name:showAsAction="ifRoom"/>

Rashmi Jain
fonte