如何将项目添加到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; } }); 

现在我试图dynamic地改变菜单。

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

应用截图

更新:

作为一个进一步的testing,我试着把这个代码分配给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,并想知道是否应该更好地使用子菜单,而不是菜单组?

Solutions Collecting From Web of "如何将项目添加到NavigationView中的菜单组"

在检查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

要添加图标,请使用MenuItem setIcon方法

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

在这里输入图像说明

我已经这样解决了:

  1. 设置菜单:

     <?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. onNavigationItemSelected() ,获取要通过命令id( 通过findItem() )展开的MenuItem ,然后从中获取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; } 

我希望,这有帮助

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

您也将分配顺序(第三参数)作为i 。 我猜这是压倒groupId。 尝试将其设置为NONE ,如上所述

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

编辑:也许这样的事情

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

Order是分类和订单的组合,所以它可能不像这样简单。