La barre d'action Android ne montre pas de débordement

90

J'ai une barre d'action dans mon application avec 3 éléments.

Seulement 2 peuvent être affichés en raison de problèmes d'espace, donc je m'attendrais à ce que le premier soit affiché et le reste à être affiché dans le débordement. Cependant, en pratique, seuls les 2 premiers éléments sont représentés et il n'y a pas de débordement détectable.

Voici le code pertinent: 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
la source
120
Si votre appareil dispose d'un bouton de menu, l'icône de débordement ne s'affiche pas. Sur quel appareil êtes-vous?
Reinier
1
le périphérique virtuel sur lequel je teste a effectivement un bouton de menu, cliqué dessus et l'élément manquant est apparu, merci!
Mats Raemen
2
@Reinier J'utilise ActionBarSherlock. Sur Galaxy Ace exécutant 2.3, il est affiché, sur Galaxy SII exécutant 4.0, il n'est pas montré. Les deux ont un bouton de menu HW.
Mister Smith
2
Je voulais confirmer que cela m'avait déconcerté que j'avais l'icône de débordement sur un nexus 7 acheter pas sur Galaxy Note II. La note avait un bouton de menu. Merci!
bsautner le
@Reinier, aidez-moi à faire face au même problème, que dois-je faire?
rupesh

Réponses:

125

Si vous souhaitez afficher les trois points, quel que soit le bouton de menu de l'appareil! alors vous pouvez appeler cette méthode dans votre classe d'application 'méthode 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
la source
32
C'est un hack horrible qui rompt la cohérence avec le reste des applications sur la plate-forme. Ne faites pas cela.
adamp le
19
Cela semble être le moindre de deux maux. Le comportement actuel est inacceptable.
biorbnA
6
C'est un excellent moyen de permettre d'avoir un débordement, la touche dure du menu ne doit plus être tolérée.
Necronet
5
Cela fonctionne très bien! Fonctionne même si l'utilisateur appuie sur le bouton de menu matériel (ce qui est génial), bien que vous entendiez l'effet sonore du menu deux fois ... est-ce que quelqu'un sait comment le faire sonner une seule fois?
Bruce
5
CE N'EST PAS UN HACK. Les développeurs doivent savoir comment appeler les hacks, car ce n'est tout simplement pas 2 + 2 sous Android. La réflexion est un gain de temps en utilisant les mécanismes Java, sinon vous passeriez des contextes à vos classes internes 24h / 24 et 7j / 7, ou vous personnaliseriez AOSP à l'infini. Pour moi, cette solution résout le problème d'avoir à remplacer et à inclure des tonnes de contenu personnalisé AOSP ET des associations privées liées juste pour le plaisir de ce que les puristes considèrent comme propre. Saviez-vous que vous ne pouvez pas forcer FASTSCROLL activé de manière cohérente pour les petites listes? Avant d'utiliser la réflexion, cela m'obligeait à copier plus de 10 ressources AOSP, pour une modification d'un caractère.
leRobot
54

Barre d'action

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);
    }

}

Téléchargez le jeu d'icônes de la barre d'action

Kirit Vaghela
la source
2
Jetez un œil au commentaire @Reinier, c'est vrai "Si votre appareil a un bouton de menu, l'icône de débordement ne s'affichera pas".
Ahmad Dwaik 'Warlock'
Je teste dans un appareil doté d'un bouton de menu et le débordement s'affiche dans mon cas. J'utilise android:showAsAction="always"pour plus d'article
Kirit Vaghela
sur quel appareil l'avez-vous testé? J'ai utilisé un neo v xperia et s #
Ahmad Dwaik 'Warlock'
1
Remarque: Votre article qui gonfle votre menu à débordement DOIT showAsAction = "always"
Kirit Vaghela
1
showAsAction n'est pas disponible dans l'espace de noms Android dans les anciens SDK. Suivez ce lien developer.android.com/training/basics/actionbar/… pour surmonter cela. Après avoir ajouté ce NS schemas.android.com/apk/res-auto , l'astuce ci-dessus a parfaitement fonctionné pour moi
chedine
42

Je me rends compte que ce n'est pas un menu à débordement, mais c'est similaire. D'accord, c'est simple mais difficile à comprendre.

Vous avez d'abord besoin d'un élément de menu que vous souhaitez utiliser comme gonfleur de débordement. Exemple

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

Une fois que vous avez votre élément, ajoutez un sous-menu contenant les éléments que vous souhaitez dans le menu à développer. Exemple:

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

En cliquant, cela gonflera les autres éléments à l'intérieur. Mon application utilise ActionBarSherlock 4.0 donc avant que cela ne fonctionne pour vous, vous devrez accéder à "SplitActionBar". (Fonctionnera toujours sur la barre d'action Android par défaut)

Voici comment procéder: dans votre fichier AndroidManifest.xml, vous devez ajouter ce code sous l'activité dans laquelle vous avez besoin du menu de débordement.

android:uiOptions="splitActionBarWhenNarrow"

REMARQUE: votre article qui gonfle votre menu à débordement DOITshowAsAction="always"

Vwola! vous avez un menu à débordement! J'espère que je vous ai aidé. :)

LeviRockerSk8er
la source
3
Belle solution, meilleure que le hack du bouton de menu.
ol0
26

Sur les appareils avec des boutons de menu matériel (Galaxy S3, têtu comme Samsung est ...) le menu de débordement se comporte comme le menu `` traditionnel '', en utilisant le bouton de menu matériel.

Lukas Batteau
la source
2
Ancienne réponse, mais avec la bibliothèque de compatibilité, il suffit de trébucher sur des résultats très étranges: 3 appareils avec bouton matériel, Note 3 Neo = le menu de débordement est affiché, le bouton de menu ne fonctionne pas, Remarque 1 = pas de débordement, le bouton de menu fonctionne, Galaxy S3, non débordement, le bouton de menu ne fonctionne pas! C'est fou.
3c71
5

Lorsque vous dites "menu de débordement", voulez-vous dire les trois points qui apparaissent à la fin pour indiquer qu'il y a plus d'éléments ... ou voulez-vous dire la barre d'actions fractionnée qui apparaît en bas pour les éléments de débordement?

Si vous parlez de la barre d'actions fractionnée, vous devez l'ajouter au fichier manifeste de votre activité

android:uiOptions="splitActionBarWhenNarrow"

Par défaut, le menu de débordement à trois points devrait se produire automatiquement, il est donc difficile de dire quel est le problème à partir des informations que vous avez fournies ci-dessus.

wnafee
la source
Je veux dire les trois points. Ce n'est pas comme si c'était à cause des articles, car à chaque changement d'articles de commande, ce sont les 2 premières icônes qui s'affichent
Mats Raemen
Dois-je fournir des informations supplémentaires pour être en mesure de déterminer le problème réel?
Mats Raemen
Quels sont votre minSdkVersion, votre targetSdkVersion et la version sur laquelle vous testez?
Sparky
5
Votre appareil dispose-t-il de boutons physiques pour le menu ou s'agit-il de boutons virtuels comme le téléphone Galaxy Nexus? Je pense que les trois points n'apparaîtront que si votre téléphone n'a pas de boutons physiques.
wnafee
5

Pour toujours afficher le débordement d'action (trois points) sur actionbarcompat:
dans le fichier menu, exemple:
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>

et dans le dossier d'activité:

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

Cela a bien fonctionné pour moi.
Testé sur Google Nexus S, Samsung S3.

MrSiro
la source
3

Il semble que sur les appareils dotés d'un bouton de menu, le menu de débordement ne s'affiche pas dans l'ActionBar. De plus, nous n'avons aucun moyen de savoir si un appareil dispose d'un bouton de menu matériel avant le niveau d'API 14 (4.0+).

Cette solution ajoute un bouton de débordement à a android.support.v7.app.ActionBarqui ouvre le menu d'options standard sur pré-Honeycomb (<3.0) uniquement, sinon le laisse au système. Dans tous les cas, vous pouvez choisir entre alwaysou ifRoompour toutes les actions.

Obtenez l'icône de débordement dans le pack d' icônes de la barre d'action .

Ajouter un menu (j'omission de certaines parties non pertinentes comme titres, commande, 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>

Supprimez notre action de débordement sur 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);
}

Appelez enfin à Activity.openOptionsMenu()partir de l'action de débordement.

Euh non. Vous ne pouvez pas ne pas appeler à openOptionsMenu()partir d'un bouton de menu ... mais si vous utilisez AndroidAnnotations, vous avez terminé facilement:

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

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

Sinon tu devrais faire quelque chose comme ça, je suppose

@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
la source
2

Essayez de changer le thème de l'application de Theme.AppCompat.Light.DarkActionBar à Theme.AppCompat.Light

Sagar Devanga
la source
2

Mettez à l' xmlns:your_app_name="http://schemas.android.com/apk/res-auto"intérieur la balise de menu et android:showAsAction="always"utilisez à la placeyour_app_name:showAsAction="always"

par exemple

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

Rashmi Jain
la source