J'ai un menu d'options sur mon Activity
avec un MenuItem
"Démarrer". Lorsque ce MenuItem
est sélectionné, je voudrais modifier le menu pour qu'il contienne un MenuItem
"Stop". Et enfin, lorsque "Stop" est sélectionné, je voudrais revenir à "Start".
Voici des parties de mon code qui ne fonctionnent pas. J'ai "Start" et "Stop" répertoriés dans mymenu.xml
Je devrais probablement supprimer "stop" lors de la création du menu:
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;
}
}
Pour ce type d'opération, je choisis généralement de ne pas modifier les éléments de menu, mais de masquer ceux dont vous n'avez pas besoin:
@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;
}
Flygenring la réponse est correcte, mais menu.findItem () est décalé et l'appelle dans onPrepareOptionsMenu (menu Menu ) produit une mauvaise expérience utilisateur. Il est préférable d'obtenir MenuItem objet une fois lors de la création du menu, puis d'appeler setVisible à chaque fois que le menu apparaît à l'écran:
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;
}
Vous devrez probablement appeler super.onPrepareOptionsMenu une fois vos modifications terminées. De la docs :
Les classes dérivées doivent toujours appeler l'implémentation de la classe de base.
J'ai la solution. Vous supprimez essentiellement le MenuItem
lorsque vous appelez removeItem()
supprimant ainsi également la référence. L'utilisation de ce code fonctionne.
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);
}
Vous devez recréer le MenuItem
. C'est aussi la raison du label false
. En fait, vous n'avez pas besoin de MenuInflater
car vous créez le Menu
via le code, donc pas besoin de fichier XML de menu.
merci pour l'info dans ce post car elle a résolu mon problème de fausses étiquettes dans mon menu. J'ai dû le modifier légèrement et avoir le code final qui fonctionne bien comme suit dans l'espoir qu'il économise du temps et de la frustration à quelqu'un d'autre. C'est une solution légèrement différente, mais le principal changement que j'ai apporté était le .setVisible à True ou False, à part que la solution i.shadrins était la mieux adaptée à mes besoins.
@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;
}
Sur Android 3.0 et supérieur, vous devez appeler invalidateOptionsMenu () pour demander que le système appelle onPrepareOptionsMenu () . Vous pouvez ensuite modifier le menu d'options dans la méthode. Vous pouvez vérifier le Modification des éléments de menu lors de l'exécution section de la Android ici https://developer.Android.com/guide/topics/ui/menus#options-men pour plus détails.