22

W grze słownej dla Androida Obecnie mam ustalony menu napompowane z left_drawer_menu.xml i składa się z 3 grup (moim kolei kolei przeciwnik i wreszcie inne rzeczy):Jak dodać element do grupy menu w NavigationView

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

teraz staram się zmienić to menu dynamicznie.

Mam instancję SQLite zawierającą wszystkie dane gry i używam IntentService do odczytu/zapisu bazy danych - ta część działa dobrze.

Mój obecny trudnością jest: z następującego kodu, nowe elementy są dodawane poza grupę 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? 
} 

app screenshot

UPDATE:

Jako dalsze badania Próbowałem przypisywać równe, a nawet żadne pozycje do 2 oddzielnych grup z tym kodem:

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

Jednak wynik wygląda chaotycznie:

app screenshot

Również odkryli (prawdopodobnie już ustalone?) Issue 176300 i zastanawiam się, czy może podmenu powinny być lepiej wykorzystane zamiast grup menu?

+1

Czy możesz opublikować swój xml tam, gdzie zdefiniowałeś swoje grupy? – random

+0

Dziękujemy, oto: https://gist.github.com/afarber/03408cf4d1e3f267589f –

+1

zobacz [this] (http://stackoverflow.com/questions/30609408/how-to-add-submenu-items-to -navigationview-programowo-zamiast-menu-xml) może ci pomóc – pRaNaY

Odpowiedz

23

Na sprawdzenie kodu MenuItemImpl Żródło

Należy więc określić kolejność w xml (podać ten sam rozkaz elementów w jednej grupie i przyrost każdego następnego Group)

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

i otrzymując odpowiednią wartość zamówienia podczas dodawania pozycji w kodzie.Więc jeśli chcesz dodać element na końcu pierwszej grupy, dodaj ją jako:

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

i jeśli chcesz dodać do drugiej grupy, dodaj ją jako:

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

problem z Twój kod może być taki, że wszystkie pozycje w xml mają domyślną wartość orderInCategory 0, więc nowy element zostanie dodany po wszystkich tych elementach.

UPDATE

Aby dodać Użyj ikony setIcon metodę MenuItem

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

To działa dobrze, a kolory są również takie same (podczas korzystania z podmenu kolory podświetlenia różnią się od oryginalnego menu). Zastanawiam się jednak, jak ustawić ikonę dynamicznie dodawanych pozycji menu? –

+1

Użyj metody 'setIcon', aby ustawić ikonę, odpowiedź została zaktualizowana. – random

+0

To wydaje się trochę głupie ... określasz grupę, do której chcesz dodać element, ale Android po prostu ignoruje ją i zrzuca na końcu listy, chyba że określisz zamówienia na produkty, które nie są nawet w tej samej grupie? Co do cholery Google? Ponadto, wciąż dodaje element po grupach dla mnie:/ – NaturalBornCamper

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

Przypisujesz także zamówienie (3. parametr) jako i. Zgaduję, że to jest przesłonięcie identyfikatora groupID. Spróbuj ustawić go jako NONE jak wspomniano here

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

Edit: Może coś w tym

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

Order jest kombinacją kategorii i porządku, więc może nie być tak proste, jak to .

+0

Niestety, 'Menu.NONE' nie naprawia problemu, a pozycje menu są wciąż dodawane na dole menu' NavigationView' - a nie w najgłębszej grupie . –

+1

Możesz spróbować obliczenia wymaganego zamówienia na podstawie pozycji już w menu i ustawić tę kolejność. – Roshan

8

enter image description here

I został rozwiązany to w ten sposób:

  1. Skonfiguruj 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. W onNavigationItemSelected(), dostać MenuItem chcesz rozszerzyć o identyfikatorze zamówienia (lub poprzez findItem()), a następnie uzyskać SubMenu z niego i dodać nowy element do niego:

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

Mam nadzieję, że pomoże

+0

Dzięki +1 za wspaniałą odpowiedź. Czy wiesz, jak dodać ikonę dla pozycji podmenu? Również kolor podświetlenia wydaje się być inny dla tych elementów ... –