J'ai une barre d'action avec un menuitem. Comment masquer / afficher cet élément de menu?
Voici ce que j'essaie de faire:
MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
J'ai une barre d'action avec un menuitem. Comment masquer / afficher cet élément de menu?
Voici ce que j'essaie de faire:
MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
Réponses:
Obtenez un MenuItem
pointage sur un tel élément, appelez- setVisible
le pour ajuster sa visibilité, puis appelez invalidateOptionsMenu()
votre activité pour que le menu ActionBar soit ajusté en conséquence.
Mise à jour: A MenuItem
n'est pas une vue régulière qui fait partie de votre mise en page. C'est quelque chose de spécial, complètement différent. Votre code revient null
pour item
et cela provoque le crash. Ce dont vous avez besoin, c'est de faire:
MenuItem item = menu.findItem(R.id.addAction);
Voici la séquence dans laquelle vous devez appeler: premier appel invalidateOptionsMenu()
puis à l'intérieur onCreateOptionsMenu(Menu)
obtenir une référence au MenuItem (en appelant menu.findItem()
) et appeler setVisible()
dessus
MenuItem
peut être null
parce que vous utilisez getItem
au lieu de findItem
. Nous ne pourrions jamais savoir, sans voir à la fois votre code et votre journal des plantages.
onCreateOptionsMenu
, et définissez la visibilité de l'élément à ce point. Ou conservez la référence jusqu'à ce que vous décidiez si elle doit être visible ou non.
invalidateOptionsMenu()
, puis à l'intérieur onCreateOptionsMenu(Menu)
obtenir une référence à MenuItem
(en appelant menu.findItem()
) et appeler setVisible()
dessus. Les réponses de suhas_sm et de P1r4nh4 présentent la bonne approche.
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 souvenir que vous souhaitez masquer le menu et appeler invalidateOptionsMenu()
et masquer les éléments dans votre onCreateOptionsMenu(...)
méthode substitué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 éléments.
if (HIDE_MENU) { return false; } else { getSupportMenuInflater().inflate(R.menu.menu_settings, menu); return true; }
La documentation indique: "Vous devez retourner true pour que le menu soit affiché; si vous retournez false, il ne sera pas affiché".
onPrepareOptionsMenu()
doit être utilisé pour afficher / masquer la logique au lieu de onCreateOptionsMenu()
car il n'est appelé qu'une seule fois, donc inutile si vous souhaitez modifier les éléments de menu après son initialisation. Alors gonflez dans onCreate, mais affichez / cachez dans onPrepare.
Oui.
invalidateOptionsMenu()
lorsque vous souhaitez masquer l'option. Cela appelleraonCreateOptionsMenu()
.onCreateOptionsMenu()
, vérifiez le drapeau / la condition et affichez-le ou masquez-le de la manière suivante:MenuItem item = menu.findItem(R.id.menu_Done); if (flag/condition)) { item.setVisible(false); } else { }
invalidateOptionsMenu
lieu de invalidateOptions
?
onCreateOptionsMenu
Vous pouvez appeler cela:
MenuItem item = menu.findItem(R.id.my_item);
item.setVisible(false);
Mise à jour:
Assurez - vous que votre code ne retourne pas null
pour item
ou il peut se bloquer l'application.
Je cherchais une réponse avec un peu plus de contexte. Maintenant que je l'ai compris, je vais ajouter cette réponse.
Par défaut, le bouton de partage sera masqué, comme défini par android:visible="false"
.
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>
Mais le bouton de partage peut éventuellement être affiché en fonction de certaines conditions.
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;
}
invalidateOptionsMenu()
pour rafraîchir le menu.
n'a pas fonctionné pour moi. J'ai dû explicitement utiliser onPrepareOptionsMenu
pour définir un élément invisible.
Utilisez donc onCreateOptionsMenu
pour créer le menu et onPrepareOptionsMenu
changer la visibilité, etc.
onPrepareOptionsMenu
semble être le bon endroit pour faire ce type d'opération: "Préparer le menu d'options standard de l'écran à afficher. Ceci est appelé juste avant que le menu ne soit affiché, chaque fois qu'il est affiché . Vous pouvez utiliser cette méthode pour activer / désactiver efficacement des éléments ou autrement modifier dynamiquement le contenu. "
invalidateOptionsMenu()
pour rafraîchir le menu.
Initialement, définissez la visibilité de l'élément de menu sur false dans le fichier de disposition 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);
}
}
Essaye ça:
MenuItem myitem = menu.findItem(R.id.my_item);
myitem.setVisible(false);
Cela a fonctionné pour moi à la fois 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);
}
La réponse P1r4nh4 fonctionne bien, je viens de la simplifier en utilisant 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);
}
}
0
et 1
n'est pas un "drapeau booléen", c'est pseudo-booléen. en outre, il n'y a aucune raison d'utiliser un booléen réel ici.
Selon le site officiel du développeur Android, OnCreateOptionMenu (menu Menu) n'est pas recommandé pour changer les éléments de menu ou les icônes, la visibilité .. etc. au moment de l'exécution.
Une fois que le système a appelé onCreateOptionsMenu (), il conserve une instance du menu que vous remplissez et n'appellera plus onCreateOptionsMenu () à moins que le menu ne soit invalidé pour une raison quelconque. Cependant, vous devez utiliser onCreateOptionsMenu () uniquement pour créer l'état de menu initial et non pour apporter des 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, comme 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 suivre les 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 des é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;
}
setVisible(false)
pour l'élément toujours visible, il ne disparaît que lorsque je clique sur les trois points (Menu lui-même). Si j'utilise invalidateOptionsMenu()
dans onPrepareOptionsMenu
les éléments se réorganisent immédiatement, mais ils perdent leurs actions (si je clique sur un élément, cela ne fait rien).
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);
}
setVisible(false)
pour l'élément toujours visible, il ne disparaît que lorsque je clique sur les trois points (Menu lui-même). Si j'utilise invalidateOptionsMenu()
dans onPrepareOptionsMenu
les éléments se réorganisent immédiatement, mais ils perdent leurs actions (si je clique sur un élément, cela ne fait rien).
Vous pouvez utiliser toolbar.getMenu().clear();
pour masquer tous les éléments de menu à la fois
En définissant la visibilité de tous les éléments du menu, le menu de la barre d'applications ou le menu de débordement seront masqués 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);
}
https://stackoverflow.com/a/21215280/466363 - répondu par Look Alterno et Sufian
.
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.
Mon someMethod () est appelé depuis plusieurs endroits, avant même onCreateOptionsMenu (), donc je dois vérifier mMenu! = Null.
Si vous avez tout fait comme dans les réponses 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 + Cliquez sur R.id.menu_open et vérifiez qu'il n'existe que dans un fichier de menu. Dans le cas où cette ressource est déjà utilisée n'importe où et chargée dans une activité, elle essaiera de s'y cacher.
La meilleure façon de masquer tous les éléments d'un menu avec une seule commande est d'utiliser "group" sur votre menu xml. Ajoutez simplement tous les éléments de menu qui seront dans votre menu de débordement à l'intérieur du même groupe.
Dans cet exemple, nous avons deux éléments de menu qui s'afficheront toujours (élément normal 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, sur votre activité (préférable 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é, assurez-vous d'enregistrer la classe de menu dans local et vérifiez toujours si le menu est nul, 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
}
Pour ceux qui utilisent la bibliothèque Appcompat: si vos sous-classes d'activité ActionBarActivity, vous pouvez appeler supportInvalidateOptionsMenu ()
Je pense qu'une meilleure approche serait d'utiliser une variable membre pour le menu, de l'initialiser dans onCreateOptionsMenu () et d'utiliser simplement setVisible () par la suite, sans invalider le menu d'options.
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);
}
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;
}
Vous essayez d'accéder à un élément de menu d'une activité, qui n'a pas accès à la portée. L'appel à rechercher l'élément de menu retournera null , car la vue n'est liée ni à l'activité ni à la mise en page 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.
Initialisez donc 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);
utilisation invalidateOptionsMenu()
afin d'appeler onPrepareOptionsMenu(menu: Menu?)
vous devez utiliser onCreateOptionsMenu () uniquement pour créer l'état de menu initial et non pour apporter des modifications pendant le cycle de vie de l'activité ...
Lorsqu'un événement se produit et que vous souhaitez effectuer une mise à jour du menu, vous devez appeler invalidateOptionsMenu () pour demander que le système appelle onPrepareOptionsMenu ().
Android kotlin, masquez ou définissez la visibilité d'un élément de menu dans la barre d'actions par programmation.
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.main_menu, menu)
val method = menu.findItem(R.id.menu_method)
method.isVisible = false //if want to show set true
return super.onCreateOptionsMenu(menu)
}