Подтвердить что ты не робот

Как добавить элемент в группу меню в NavigationView

В игровой игре для Android у меня в настоящее время есть жестко настроенное меню, раздутое от left_drawer_menu.xml и состоящее из 3 групп (мой ход, противник поворачивается и, наконец, другие вещи):

скриншот приложения

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

Теперь я пытаюсь изменить это меню динамически.

У меня есть экземпляр SQLite, содержащий все игровые данные, и используйте IntentService для чтения/записи базы данных - эта часть работает нормально.

Моя текущая трудность: со следующим кодом новые элементы добавляются за пределами группы R.id.my_move:

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

скриншот приложения

UPDATE:

В качестве дополнительного теста я попытался назначить четные и даже не элементы для 2 отдельных групп с помощью этого кода:

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

Однако результат выглядит хаотичным:

скриншот приложения

Также я обнаружил (возможно, уже исправленный?) выпуск 176300 и задаюсь вопросом, следует ли лучше использовать подменю вместо групп меню?

4b9b3361

Ответ 1

При проверке MenuItemImpl исходного кода

     ...
     *    @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) {

Итак, вы должны определить порядок в своем xml (указать тот же порядок для элементов в одной группе и прирастить в каждой следующей группе)

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

и укажите значение заказа при добавлении элемента в свой код. Поэтому, если вы хотите добавить элемент в конце первой группы, добавьте его как:

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

и если вы хотите добавить вторую группу, добавьте ее как:

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

Проблема с вашим кодом может заключаться в том, что все элементы в xml имеют значение по умолчанию orderInCategory 0, и поэтому новый элемент добавляется после все эти пункты.

UPDATE

Чтобы добавить значок, используйте setIcon метод MenuItem

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

Ответ 2

введите описание изображения здесь

Я решил это так:

  • Настройте меню:

    <?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 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>
    
  • В onNavigationItemSelected(), получите MenuItem, который вы хотите развернуть по идентификатору заказа ( или через findItem()), затем получите SubMenu от него и добавьте в него новый элемент

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

Надеюсь, это поможет

Ответ 3

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

Вы также назначаете порядок (третий параметр) как i. Я предполагаю, что это переопределяет groupId. Попробуйте установить его как NONE, как указано здесь

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

Edit: Может быть, что-то вроде этого

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

Order представляет собой комбинацию категории и порядка, поэтому она может быть не такой прямой, как эта.