web-dev-qa-db-fra.com

Comment ajouter un élément à un groupe de menus dans NavigationView

Dans un jeu Word pour Android J'ai actuellement un menu codé en dur gonflé de left_drawer_menu.xml et composé de 3 groupes (mon tour, le tour de l'adversaire et enfin d'autres trucs):

app screenshot

mLeftDrawer = (NavigationView) findViewById(R.id.left_drawer);
mLeftDrawer.setNavigationItemSelectedListener(
        new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(final MenuItem menuItem) {
                Menu menu = mLeftDrawer.getMenu();

                if (menuItem.getGroupId() == R.id.my_move) {
                    menu.setGroupCheckable(R.id.my_move, true, true);
                    menu.setGroupCheckable(R.id.his_move, false, false);
                    menu.setGroupCheckable(R.id.extras, false, false);
                } else if (menuItem.getGroupId() == R.id.his_move) {
                    menu.setGroupCheckable(R.id.my_move, false, false);
                    menu.setGroupCheckable(R.id.his_move, true, true);
                    menu.setGroupCheckable(R.id.extras, false, false);
                } else if (menuItem.getGroupId() == R.id.extras) {
                    menu.setGroupCheckable(R.id.my_move, false, false);
                    menu.setGroupCheckable(R.id.his_move, false, false);
                    menu.setGroupCheckable(R.id.extras, true, true);
                }

                menuItem.setChecked(true);
                mLeftItem = menuItem.getItemId();
                mDrawerLayout.closeDrawer(mLeftDrawer);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (mLeftItem == R.id.start) {
                            startNewGame();
                        } 
                    }
                },DRAWER_CLOSE_DELAY);

                return true;
            }
        });

Maintenant j'essaye de changer ce menu dynamiquement.

J'ai une instance SQLite contenant toutes les données du jeu et j'utilise IntentService pour lire/écrire la base de données - cette partie fonctionne bien.

Ma difficulté actuelle est: avec le code suivant, les nouveaux éléments sont ajoutés à l'extérieur le R.id.my_move groupe:

if (mLeftItem == R.id.start) {
    startNewGame();

    Random r = new Random();
    int i = r.nextInt(100);
    menu.add(R.id.my_move, i, i, "Item " + i);   // why is my_move ignored?
} 

app screenshot

MISE À JOUR:

Comme test supplémentaire, j'ai essayé d'attribuer des éléments pairs et même pas à 2 groupes distincts avec ce code:

Random r = new Random();
int i = r.nextInt(100);
int group = 1 + (i % 2); // can be 1 or 2
menu.add(group, i, i, "Item " + i);

Cependant, le résultat semble chaotique:

app screenshot

J'ai également découvert le (probablement déjà corrigé?) problème 1763 et je me demande si les sous-menus devraient être mieux utilisés à la place des groupes de menus?

29
Alexander Farber

Lors de la vérification MenuItemImpl code source

     ...
     *    @param group Item ordering grouping control. The item will be added after
     *            all other items whose order is <= this number, and before any
     *            that are larger than it. This can also be used to define
     *            groups of items for batch state changes. Normally use 0.
     ...

    MenuItemImpl(MenuBuilder menu, int group, int id, int categoryOrder, int ordering,
        CharSequence title, int showAsAction) {

Vous devez donc définir l'ordre dans votre xml (donner le même ordre aux éléments dans un groupe et incrémenter dans chaque groupe suivant)

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <group Android:id="@+id/my_move" Android:checkableBehavior="single">
        <item
            Android:orderInCategory="0"
            Android:id="@+id/game1"
            Android:icon="@drawable/ic_stars_black_24dp"
            Android:title="Game #1" />
        <item
            Android:orderInCategory="0"
            Android:id="@+id/game2"
            Android:icon="@drawable/ic_stars_black_24dp"
            Android:title="Game #2" />
    </group>
    <group Android:id="@+id/his_move" Android:checkableBehavior="single">
        <item
            Android:orderInCategory="1"
            Android:id="@+id/game5"
            Android:icon="@drawable/ic_clock_black_24dp"
            Android:title="Game #5" />
        <item
            Android:orderInCategory="1"
            Android:id="@+id/game6"
            Android:icon="@drawable/ic_clock_black_24dp"
            Android:title="Game #6" />
        <item
            Android:orderInCategory="1"
            Android:id="@+id/game7"
            Android:icon="@drawable/ic_clock_black_24dp"
            Android:title="Game #7" />
    </group>
    .....

</menu>

et donnez une valeur de commande appropriée tout en ajoutant l'article dans votre code. Donc, si vous souhaitez ajouter l'élément à la fin du premier groupe, ajoutez-le comme:

menu.add(R.id.my_move, Menu.NONE, 0, "Item1");

et si vous souhaitez ajouter au deuxième groupe, ajoutez-le comme:

menu.add(R.id.his_move, Menu.NONE, 1, "Item2");

Le problème avec votre code pourrait être que tous les éléments du XML ont par défaut orderInCategory 0 et donc le nouvel élément est ajouté après tous ces éléments.

[~ # ~] mise à jour [~ # ~]

Pour ajouter une icône, utilisez la méthode setIcon pour MenuItem

menu.add(R.id.my_move, Menu.NONE, 0, "Item1").setIcon(R.drawable.ic_stars_black_24dp);
35
random

enter image description here

Je l'ai résolu de cette façon:

  1. Configurer le menu:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <item Android:title="my moves"
              Android:id="@+id/submenu_1">
            <menu>
                <item
                    Android:id="@+id/my_dummy_item_1"
                    Android:icon="@drawable/ic_menu_camera"
                    Android:title="Import" />
                <item
                    Android:id="@+id/my_dummy_item_2"
                    Android:icon="@drawable/ic_menu_gallery"
                    Android:title="Gallery" />
                <item
                    Android:id="@+id/add_item"
                    Android:icon="@drawable/ic_menu_manage"
                    Android:title="Add Item" />
            </menu>
        </item>
        <item Android:title="opponent's moves"
              Android:id="@+id/submenu_2">
            <menu>
                <item
                    Android:id="@+id/opponent_dummy_item_1"
                    Android:icon="@drawable/ic_menu_camera"
                    Android:title="Import" />
                <item
                    Android:id="@+id/opponent_dummy_item_2"
                    Android:icon="@drawable/ic_menu_gallery"
                    Android:title="Gallery" />
                <item
                    Android:id="@+id/opponent_dummy_item_3"
                    Android:icon="@drawable/ic_menu_manage"
                    Android:title="Tools" />
            </menu>
        </item>
    </menu>
    
  2. Dans onNavigationItemSelected(), obtenez MenuItem que vous souhaitez développer par l'id de la commande ( ou via findItem()), puis récupérez SubMenu et ajoutez-y un nouvel élément:

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        int id = item.getItemId();
    
        if (id == R.id.add_item) {
            Random r = new Random();
            int i = r.nextInt(100);
            MenuItem myMoveGroupItem = navigationView.getMenu().getItem(0);
            // MenuItem myMoveGroupItem = navigationView.getMenu().findItem(R.id.submenu_1);  -- it also works!
            SubMenu subMenu = myMoveGroupItem.getSubMenu();
            subMenu.add("Item "+i);
        }
    
        return true;
    }
    

J'espère que ça aide

14
Konstantin Loginov
menu.add(R.id.my_move, i, i, "Item " + i);

Vous affectez également l'ordre (3e paramètre) en tant que i. Je suppose que cela remplace le groupId. Essayez de le définir comme NONE comme mentionné ici

menu.add(R.id.my_move, i, NONE, "Item " + i);

Edit: Peut-être quelque chose comme ça

MenuItem lastItem = menu.findItem(R.id.<lastItemId>);
int lastOrder= lastItem.getOrder();
menu.add(R.id.my_move, i, lastOrder-5, "Item " + i);

Order est une combinaison de catégorie et d'ordre, donc ce n'est peut-être pas aussi simple que cela.

2
Roshan