Как добавить элемент в группу меню в 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 и задаюсь вопросом, следует ли лучше использовать подменю вместо групп меню?
Ответы
Ответ 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
представляет собой комбинацию категории и порядка, поэтому она может быть не такой прямой, как эта.