web-dev-qa-db-fra.com

Comment masquer un élément de menu dans la barre d'actions?

J'ai une barre d'action avec un menuitem. Comment puis-je masquer/afficher cet élément de menu?

C'est ce que j'essaie de faire:

MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
291
Stir Zoltán

Obtenez une MenuItem pointant vers cet élément, appelez setVisible pour ajuster sa visibilité, puis appelez invalidateOptionsMenu() sur votre activité pour que le menu ActionBar soit ajusté en conséquence.

Mise à jour: Une MenuItem n'est pas une vue régulière faisant partie de votre mise en page. C'est quelque chose de spécial, complètement différent. Votre code retourne null pour item et cela provoque le blocage. Au lieu de cela, vous devez faire:

MenuItem item = menu.findItem(R.id.addAction);

Voici la séquence dans laquelle vous devez appeler: Appelez d'abord invalidateOptionsMenu() puis à l'intérieur de onCreateOptionsMenu(Menu) obtenez une référence à MenuItem (en appelant menu.findItem()) et appelez setVisible()

428
K-ballo

Trouvé un addendum à cette question:

Si vous souhaitez modifier la visibilité de vos éléments de menu lors de vos déplacements, il vous suffit de définir une variable membre dans votre activité pour vous rappeler que vous souhaitez masquer le menu, appeler invalidateOptionsMenu() et masquer les éléments de votre méthode onCreateOptionsMenu(...) remplacée.

//anywhere in your code
...
mState = HIDE_MENU; // setting state
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == HIDE_MENU)
    {
        for (int i = 0; i < menu.size(); i++)
            menu.getItem(i).setVisible(false);
    }
}

Dans mon exemple, j'ai caché tous les objets.

142
P1r4nh4

Oui. 

  1. Vous pouvez définir un drapeau/une condition.
  2. Appelez invalidateOptionsMenu() lorsque vous souhaitez masquer l'option. Ceci appellera onCreateOptionsMenu().
  3. Dans onCreateOptionsMenu(), recherchez l'indicateur/la condition et affichez ou Masquez-le de la manière suivante:
MenuItem item = menu.findItem(R.id.menu_Done);

if (flag/condition)) {
  item.setVisible(false); 
} else { }
77
suhas_sm

Vous pouvez appeler ça:

MenuItem item = menu.findItem(R.id.my_item);
item.setVisible(false);

Mettre à jour:

Assurez-vous que votre code ne renvoie pas null pour item sinon l'application pourrait se bloquer.

36
elias

Je cherchais une réponse avec un peu plus de contexte. Maintenant que j'ai compris, je vais ajouter cette réponse.

Bouton Cacher par défaut dans le menu xml

Par défaut, le bouton de partage sera masqué, comme défini par Android:visible="false".

 enter image description here

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
      xmlns:app="http://schemas.Android.com/apk/res-auto">

    <!-- hide share button by default -->
    <item
        Android:id="@+id/menu_action_share"
        Android:icon="@drawable/ic_share_white_24dp"
        Android:visible="false"     
        Android:title="Share"
        app:showAsAction="always"/>

    <item
        Android:id="@+id/menu_action_settings"
        Android:icon="@drawable/ic_settings_white_24dp"
        Android:title="Setting"
        app:showAsAction="ifRoom"/>

</menu>

Afficher le bouton dans le code

Mais le bouton de partage peut éventuellement être affiché en fonction de certaines conditions.

 enter image description here

MainActivity.Java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem shareItem = menu.findItem(R.id.menu_action_share);

    // show the button when some condition is true
    if (someCondition) {        
        shareItem.setVisible(true);
    }

    return true;
}

Voir également

28
Suragch

n'a pas fonctionné pour moi. J'ai dû utiliser explicitement onPrepareOptionsMenu pour définir un élément invisible.

Utilisez donc onCreateOptionsMenu pour créer le menu et onPrepareOptionsMenu pour changer la visibilité, etc.

23
hotzen

Cela a fonctionné pour moi de l'activité et du fragment

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    if (menu.findItem(R.id.action_messages) != null)
        menu.findItem(R.id.action_messages).setVisible(false);
}
7
Bala Vishnu

Initialement, définissez la visibilité de l'élément de menu sur false dans le fichier de présentation de menu comme suit:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">
    <item
        Android:visible="false"
        Android:id="@+id/action_do_something"
        Android:title="@string/txt_do_something"
        app:showAsAction="always|withText"
        Android:icon="@drawable/ic_done"/>
</menu>

Vous pouvez ensuite simplement définir la visibilité de l'élément de menu sur false dans votre onCreateOptionsMenu () après avoir gonflé le menu.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(menu,R.menu.menu);
    MenuItem item = menu.findItem(R.id.menuItemId);
    if (item != null){
        item.setVisible(false);
    }
}
7
Akhila

La réponse P1r4nh4 fonctionne bien, je l'ai simplement simplifiée à l'aide d'un drapeau booléen

public int mState = 0; //at the top of the code
//where you want to trigger the hide action
mState = 1; // to hide or mState = 0; to show
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == 1) //1 is true, 0 is false
    {
        //hide only option 2
            menu.getItem(2).setVisible(false);
    }
}
6
Hiram

Vous pouvez utiliser toolbar.getMenu().clear(); pour masquer tous les éléments de menu à la fois. 

3
Ajeet Yadav

définissez une valeur sur une variable et appelez invalidateOptionsMenu ();

par exemple

    selectedid=arg2;
            invalidateOptionsMenu();


 public boolean onPrepareOptionsMenu(Menu menu) {

    if(selectedid==1){
        menu.findItem(R.id.action_setting).setVisible(false);
        menu.findItem(R.id.action_s2).setVisible(false);
        menu.findItem(R.id.action_s3).setVisible(false);
    }
    else{
        if(selectedid==2){
            menu.findItem(R.id.action_search).setVisible(false);
            menu.findItem(R.id.action_s4).setVisible(false);
            menu.findItem(R.id.action_s5).setVisible(false);
        }
    }
    return super.onPrepareOptionsMenu(menu);
}
3
zacharia

Selon le site officiel Android Developer, OnCreateOptionMenu (menu) n'est pas recommandé pour modifier les éléments de menu ou les icônes, la visibilité..etc au runtime.

Une fois que le système a appelé onCreateOptionsMenu (), il conserve une instance du menu que vous remplissez et n'appelle plus onCreateOptionsMenu () à moins que le menu ne soit invalidé pour une raison quelconque. Toutefois, vous ne devez utiliser onCreateOptionsMenu () que pour créer l'état de menu initial et ne pas apporter de modifications au cours du cycle de vie de l'activité.

Si vous souhaitez modifier le menu d'options en fonction des événements qui se produisent pendant le cycle de vie de l'activité, vous pouvez le faire dans la méthode onPrepareOptionsMenu (). Cette méthode vous transmet l'objet Menu tel qu'il existe actuellement afin que vous puissiez le modifier, par exemple ajouter, supprimer ou désactiver des éléments. (Les fragments fournissent également un rappel onPrepareOptionsMenu ().) --AndroidDeveloper Official Site -

Comme recommandé Vous pouvez utiliser cette méthode onOptionsItemSelected (élément MenuItem) pour effectuer le suivi des entrées utilisateur.

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.edit) {
        Intent intent = new Intent(this, ExampleActivity.class);
        intent.putExtra(BUNDLE_KEY, mConnection);
        startActivityForResult(intent, PICK_CHANGE_REQUEST);
        return true;
    } else if (id == R.id.delete) {
        showDialog(this);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

Si vous devez modifier les éléments de menu au moment de l'exécution, vous pouvez utiliser onPrepareOptionsMenu (menu menu) pour les modifier.

@Override
public boolean onPrepareOptionsMenu(Menu menu){

    if (Utils.checkNetworkStatus(ExampleActivity.this)) {
        menu.findItem(R.id.edit).setVisible(true);
        menu.findItem(R.id.delete).setVisible(true);
    }else {
        menu.findItem(R.id.edit).setVisible(false);
        menu.findItem(R.id.delete).setVisible(false);
    }
    return true;
} 
3

https://stackoverflow.com/a/21215280/466363 - répondu par Look Alterno et Sufian

  • ActivityCompat.invalidateOptionsMenu () ne rappelle pas OnPrepareOptionsMenu (); il suffit de mettre à jour le menu directement.
  • My someMethod () est appelé de plusieurs endroits, même avant OnCreateOptionsMenu (), je dois donc vérifier mMenu! = Null.
  • devrait fonctionner avec API 8

.

private Menu mMenu;
   @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
       inflater.inflate(R.menu.track_fragment, menu);
       mMenu = menu;
       }
   ...
   private void someMethod() {
   ...
       if (mMenu != null) {
          MenuItem item = mMenu.findItem(R.id.new_track);
          if (item != null) {
               item.setVisible(false);
               ActivityCompat.invalidateOptionsMenu(this.getActivity());
           }
       }
   ...
   }
  • ActivityCompat.invalidateOptionsMenu () ne rappelle pas OnPrepareOptionsMenu (); il suffit de mettre à jour le menu directement.

  • My someMethod () est appelé de plusieurs endroits, même avant OnCreateOptionsMenu (), je dois donc vérifier mMenu! = Null.

  • devrait fonctionner avec API 8
2
Shimon Doodkin

Si vous avez tout fait comme indiqué ci-dessus, mais qu'un élément de menu est toujours visible, vérifiez que vous faites référence à la ressource unique . Par exemple, dans onCreateOptionsMenu ou onPrepareOptionsMenu

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    MenuItem menuOpen = menu.findItem(R.id.menu_open);
    menuOpen.setVisible(false);
}

Ctrl + Clique sur R.id.menu_open et vérifiez qu’il n’existe que dans un seul fichier de menu. Si cette ressource est déjà utilisée n’importe où et chargée dans une activité, elle essaiera de s'y cacher.

2
CoolMind

En définissant la visibilité de tous les éléments du menu, le menu de la barre d’application ou du menu de débordement sera masqué automatiquement

Exemple

private Menu menu_change_language;

...

...

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    ...
    ...
    menu_change_language = menu;
    menu_change_language.findItem(R.id.menu_change_language)
           .setVisible(true);

    return super.onCreateOptionsMenu(menu);
}

Avant de passer à un autre fragment, utilisez le code ci-dessous:

if(menu_change_language != null){                 
    menu_change_language.findItem(R.id.menu_change_language)
       .setVisible(false);
}
2
Hantash Nadeem

ce code a fonctionné pour moi

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu,menu);
    if (Application.sharedPreferences.getInt("type",1) == 2)
    {
        menuItem = menu.findItem(R.id.menu_travel_orders);
        menuItem.setVisible(false);
    }
    return super.onCreateOptionsMenu(menu);
}
1
saigopi

Je pense qu'une meilleure approche consisterait à utiliser une variable membre pour le menu, à l'initialiser dans onCreateOptionsMenu () et à utiliser simplement setVisible () par la suite, sans invalider le menu d'options.

0
Catalin Clabescu

Pour ceux qui utilisent la bibliothèque Appcompat: Si votre activité est sous-classe ActionBarActivity, vous pouvez appeler supportInvalidateOptionsMenu ().

Vu ici: https://stackoverflow.com/a/19649877/1562524

0
RuideraJ

Le meilleur moyen de masquer tous les éléments d'un menu à l'aide d'une seule commande consiste à utiliser "groupe" dans votre menu xml. Ajoutez simplement tous les éléments de menu qui figureront dans votre menu de dépassement au sein du même groupe.

Dans cet exemple, nous avons deux éléments de menu qui seront toujours affichés (élément standard et recherche) et trois éléments de débordement:

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">

    <item
        Android:id="@+id/someItemNotToHide1"
        Android:title="ITEM"
        app:showAsAction="always" />

    <item
        Android:id="@+id/someItemNotToHide2"
        Android:icon="@Android:drawable/ic_menu_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="Android.support.v7.widget.SearchView"
        Android:title="Search"/>

    <group Android:id="@+id/overFlowItemsToHide">
    <item Android:id="@+id/someID" 
    Android:orderInCategory="1" app:showAsAction="never" />
    <item Android:id="@+id/someID2" 
    Android:orderInCategory="1" app:showAsAction="never" />
    <item Android:id="@+id/someID3" 
    Android:orderInCategory="1" app:showAsAction="never" />
    </group>
</menu>

Ensuite, pour votre activité (de préférence sur onCreateOptionsMenu), utilisez la commande setGroupVisible pour définir la visibilité de tous les éléments de menu sur false ou true.

public boolean onCreateOptionsMenu(Menu menu) {
   menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible
}

Si vous souhaitez utiliser cette commande n'importe où ailleurs dans votre activité, veillez à enregistrer la classe de menu en local et vérifiez toujours si menu est null, car vous pouvez l'exécuter avant createOptionsMenu:

Menu menu;

public boolean onCreateOptionsMenu(Menu menu) {
       this.menu = menu;

}

public void hideMenus() {
       if (menu != null) menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible       
}
0
Adriano Moutinho

Cette approche a fonctionné pour moi:

private  Menu thismenu;

if (condition)
{
   if(thismenu != null)
   {
       thismenu.findItem(R.id.menu_save).setVisible(true);
       Toast.makeText(ProfileActivity.this, 
    ""+thismenu.findItem(R.id.menu_save).getTitle(),
                Toast.LENGTH_SHORT).show();
   }else
   {
       thismenu.findItem(R.id.menu_save).setVisible(false);
   }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   getMenuInflater().inflate(R.menu.profile_menu, menu);
   thismenu = menu;

   return true;
}
0
Forest baba

Vous essayez d'accéder à un élément de menu d'une activité qui n'a pas accès à la portée. L'appel pour rechercher l'élément de menu retournera null , car la vue n'est pas liée à ni l'activité ni la présentation à partir de laquelle vous appelez.

Les éléments de menu sont liés à des éléments tels que " Barre de navigation " qui, à leur tour, sont liés à l'activité correspondante.

Donc initialisez ces vues dans activity (), puis accédez aux éléments de menu avec ces vues.

Navigation navView;
navView = findViewById(R.id.navigationView);

MenuItem item = navView.getMenu().findItem(R.id.item_hosting);
item.setVisible(false);
0
VeeyaaR

Essaye ça:

MenuItem myitem = menu.findItem(R.id.my_item);
myitem.setVisible(false);
0
mohamad sheikhi

utiliser invalidateOptionsMenu()

pour appeler onPrepareOptionsMenu(menu: Menu?)

vous ne devez utiliser onCreateOptionsMenu () que pour créer l'état de menu initial et ne pas apporter de modifications au cours du cycle de vie de l'activité ...

Lorsqu'un événement se produit et que vous souhaitez effectuer une mise à jour de menu, vous devez appeler invalidateOptionsMenu () pour demander l'appel système onPrepareOptionsMenu ().

https://developer.Android.com/guide/topics/ui/menus

0
Dan Alboteanu