2010-11-16 14 views
41

Mam menu opcji na moim Activity z MenuItem "Start". Po wybraniu tego MenuItem chciałbym zmienić Menu tak, aby zawierało "Zatrzymanie" MenuItem. I w końcu, gdy wybrano "Stop", chciałbym zmienić z powrotem na "Start".Jak zmienić element menu w menu opcji na urządzeniu z systemem Android?

Oto części mojego kodu, który nie działa. Mam zarówno „start” i „stop” wymienione w mymenu.xml I prawdopodobnie powinien usunąć „stop”, gdy menu jest tworzony:

public class MyActivity extends Activity { 
    private boolean isStarted = false; 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     menu.removeItem(R.id.stop); 
     inflater.inflate(R.menu.mymenu, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case R.id.start: 
      isStarted = true; 
      return true; 
     case R.id.stop: 
      isStarted = false; 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
     } 
    } 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
     if(isStarted) { 
      menu.removeItem(R.id.start); 
      menu.add(R.id.stop); 
     } else { 
      menu.removeItem(R.id.stop); 
      menu.add(R.id.start); 
     } 
     return true; 
    } 
} 
+1

Czy próbowałeś już usunąć Stop po utworzeniu menu? Kod wygląda dobrze. Nie widzę niczego, co mogłoby spowodować problemy inne niż to. –

+0

@Octavian: Próbowałem z 'menu.removeItem (R.id.stop);' after 'getMenuInflater();' ale to nie działało. Dostaję dwa elementy menu, jeden "start" i jeden "false" (powinien być "stop"), albo menu zawiesza się, kiedy powinienem się pokazać. – Jonas

+1

gdzie próbujesz wywołać 'removeItem()'? W 'onPrepareOptionsMenu()'? –

Odpowiedz

94

Dla tego typu operacji I zazwyczaj wybrać, aby nie zmieniać pozycje menu, ale po prostu ukryć te, które nie potrzebują:

@Override 
public boolean onPrepareOptionsMenu(Menu menu) { 
    super.onPrepareOptionsMenu(menu); 
    menu.findItem(R.id.start).setVisible(!isStarted); 
    menu.findItem(R.id.stop).setVisible(isStarted); 
    return true; 
} 
+0

Po prostu zobaczyłem, że zapomniałem zadzwonić do nadklasy, zgodnie z sugestią wcześniejszą i określoną w [docs] (http: // developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu%28android.view.Menu%29) i [źródło] (http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/ core/java/android/app/Activity.java & d = 3 & l = 2272) – Flygenring

+0

I tylko po to, aby zaktualizować, źródło można znaleźć pod adresem http://grepcode.com/file/repository.grepcode.com/java/ext/com. google.android/android/2.3_r1/android/app/Activity.java?av=f#2272 – Flygenring

6

Prawdopodobnie trzeba zadzwonić super.onPrepareOptionsMenu po zakończeniu wprowadzania zmian. Z docs:

klas wynikających powinien zawsze zadzwonić aż do klasy bazowej realizacji.

+0

+1 za dostarczenie poprawnej odpowiedzi, nawet jeśli nie jest to rozwiązanie. –

3

Mam rozwiązanie. Zasadniczo usuwasz MenuItem podczas wywoływania removeItem(), tym samym usuwając odniesienie. Używanie tego kodu działa.

private boolean isStarted = false; 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
    case 1: 
     isStarted = true; 
     return true; 
    case 0: 
     isStarted = false; 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 

@Override 
public boolean onPrepareOptionsMenu(Menu menu) { 

    if(isStarted) { 
     menu.removeItem(1); 
     menu.add(0, 0, 0, "Stop"); 
    } else { 
     menu.removeItem(0); 
     menu.add(0, 1, 0, "Start"); 
    } 

    return super.onPrepareOptionsMenu(menu); 
} 

Musisz ponownie utworzyć MenuItem. Jest to również powód etykiety false. W rzeczywistości nie potrzebujesz MenuInflater podczas tworzenia kodu Menu, więc nie potrzebujesz też żadnego pliku XML menu.

20

Flygenring odpowiedź jest poprawna, ale menu.findItem () jest opóźniony i wywołuje go w zakresie onPrepareOptionsMenu (menu menu) powoduje złe wrażenia użytkownika. Lepiej dostać MenuItem Przedmiotem raz podczas menu tworzenia, a potem po prostu zadzwonić setVisible każdym razem menu occures na ekranie:

MenuItem mDynamicMenuItem; 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     // Get dynamic menu item 
     mDynamicMenuItem = menu.findItem(R.id.menu_item); 
     return true; 
    } 

    // Prepare the Screen's standard options menu to be displayed. This is called right 
    // before the menu is shown, every time it is shown. You can use this method to 
    // efficiently enable/disable items or otherwise dynamically modify the contents. 
    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
     super.onPrepareOptionsMenu(menu); 
     // Here is just a good place to update item 
     mDynamicMenuItem.setVisible(isVisible); 
     return true; 
    } 
1

Dzięki za info w tym poście, jak rozwiązać mój problem fałszywych etykiet w moim menu. Musiałem go nieco zmodyfikować i mieć ostateczny kod, który działa dobrze w następujący sposób, w nadziei, że uratuje kogoś innego czas i frustrację. Jest to nieco inne rozwiązanie, ale główną zmianą, jaką wprowadziłem, było ustawienie .setVisible na True lub False, poza tym rozwiązanie i.shadrins najlepiej pasowało do moich potrzeb.

@Override 
public boolean onPrepareOptionsMenu(Menu menu) { 
    super.onPrepareOptionsMenu(menu); 

    if(loggedIn) 
    { 
     logIn.setVisible(false); 
     logOut.setVisible(true); 
    } 
    else 
    { 
     logIn.setVisible(true); 
     logOut.setVisible(false); 
    } 
    return true; 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    super.onCreateOptionsMenu(menu); 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    logIn = menu.findItem(R.id.loggedOut); 
    logOut = menu.findItem(R.id.loggedIn); 
    return true; 
} 
+0

W jakim pliku należy go umieścić? –

Powiązane problemy