web-dev-qa-db-fra.com

Android: Comment activer/désactiver l'option du menu d'option lors d'un clic sur un bouton?

Je peux facilement le faire lorsque j'utilise les méthodes onCreateOptionsMenu ou onOptionsItemSelected.

Mais j'ai un bouton quelque part dans l'écran et en cliquant dessus, il devrait activer/désactiver les éléments du menu contextuel.

112
Vikas

Quoi qu'il en soit, la documentation couvre tout.

Modification des éléments de menu à l'exécution

Une fois l'activité créée, le fichier La méthode onCreateOptionsMenu() est appelée une seule fois, comme décrit ci-dessus. Le Le système garde et réutilise la Menuvous définir dans cette méthode jusqu'à votre l'activité est détruite. Si tu veux changez le menu d'options à tout moment après il est créé en premier, vous devez remplacer la méthode onPrepareOptionsMenu() . Cela vous passe l'objet Menu tel quel existe actuellement. Ceci est utile si vous souhaitez supprimer, ajouter, désactiver ou activer les éléments de menu en fonction du état actuel de votre application.

Par exemple. 

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    if (isFinalized) {
        menu.getItem(1).setEnabled(false);
        // You can also use something like:
        // menu.findItem(R.id.example_foobar).setEnabled(false);
    }
    return true;
}

Sur Android 3.0 et versions ultérieures, le menu des options est considéré comme toujours ouvert lorsque des éléments de menu sont présentés dans la barre d'action. 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().

243
Vikas

Sur toutes les versions d'Android, le moyen le plus simple: utilisez ceci pour AFFICHER une icône d'action de menu comme désactivée ET la rendre aussi fonctionnelle:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

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

    if (myItemShouldBeEnabled) {
        item.setEnabled(true);
        item.getIcon().setAlpha(255);
    } else {
        // disabled
        item.setEnabled(false);
        item.getIcon().setAlpha(130);
    }
}
57
Frank

Vous pouvez enregistrer l'élément en tant que variable lors de la création du menu d'options, puis modifier ses propriétés à volonté.

private MenuItem securedConnection;
private MenuItem insecuredConnection;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.connect_menu, menu);
    securedConnection = menu.getItem(0);
    insecuredConnection =  menu.getItem(1);
    return true;
}

public void foo(){
       securedConnection.setEnabled(true);
}    
39
nir

simplifier la version de @Vikas 

@Override
public boolean onPrepareOptionsMenu (Menu menu) {

    menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
    return true;
}
5
Kosrat D. Ahmad

la meilleure solution lorsque vous jouez dans le tiroir de navigation

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.setGroupVisible(0,false);
        return true;
    }
2
Prashant Gosai

Comment mettre à jour le menu actuel afin d'activer ou de désactiver les éléments lorsqu'une tâche asynchrone est effectuée.

Dans mon cas d'utilisation, je devais désactiver mon menu pendant le chargement des données de ma tâche Async, puis après le chargement de toutes les données, je devais réactiver tout le menu afin de permettre à l'utilisateur de l'utiliser.

Cela empêchait l'application de laisser les utilisateurs cliquer sur les éléments de menu pendant le chargement des données.

Premièrement, je déclare une variable d'état. Si la variable est 0, le menu est affiché. Si cette variable est 1, le menu est masqué.

private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.

Puis dans mon onCreateOptionsMenu() je vérifie cette variable, si elle vaut 1, je désactive tous mes éléments, sinon, je les montre seulement tous

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);

        if(mMenuState==1){
            for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(false);
            }
        }else{
             for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(true);
            }
        }

        return super.onCreateOptionsMenu(menu);
    }

Désormais, lorsque mon activité commencera, onCreateOptionsMenu() sera appelé une seule fois et tous mes objets disparaîtront, car je leur ai configuré l'état au début.

Ensuite, je crée une AsyncTask où je règle cette variable d'état à 0 dans ma onPostExecute() 

Cette étape est très importante!

Lorsque vous appelez invalidateOptionsMenu();, il relancera onCreateOptionsMenu();

Donc, après avoir mis mon état à 0, je viens de redessiner tout le menu mais cette fois avec ma variable sur 0, cela dit, tout le menu sera affiché après que tout le processus asynchrone soit terminé, puis mon utilisateur pourra utiliser le menu .

 public class LoadMyGroups extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration. 

        }

        @Override
        protected Void doInBackground(Void... voids) {
           //Background work

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
            invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu

        }
    }

Résultats

 enter image description here

2
Gastón Saillén
  @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            switch (item.getItemId()) {

                case R.id.item_id:

                       //Your Code....

                        item.setEnabled(false);
                        break;
              }
            return super.onOptionsItemSelected(item);
     }
1
Tousif Akram

Une réponse plus moderne à une vieille question:

MainActivity.kt

private var myMenuIconEnabled by Delegates.observable(true) { _, old, new ->
    if (new != old) invalidateOptionsMenu()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    findViewById<Button>(R.id.my_button).setOnClickListener { myMenuIconEnabled = false }
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu_main_activity, menu)
    return super.onCreateOptionsMenu(menu)
}

override fun onPrepareOptionsMenu(menu: Menu): Boolean {
    menu.findItem(R.id.action_my_action).isEnabled = myMenuIconEnabled
    return super.onPrepareOptionsMenu(menu)
}

menu_main_activity.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">
<item
    Android:id="@+id/action_my_action"
    Android:icon="@drawable/ic_my_icon_24dp"
    app:iconTint="@drawable/menu_item_icon_selector"
    Android:title="My title"
    app:showAsAction="always" />
</menu>

menu_item_icon_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:color="?enabledMenuIconColor" Android:state_enabled="true" />
<item Android:color="?disabledMenuIconColor" />

attrs.xml

<resources>   
    <attr name="enabledMenuIconColor" format="reference|color"/>
    <attr name="disabledMenuIconColor" format="reference|color"/>
</resources>

styles.xml or themes.xml

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="disabledMenuIconColor">@color/white_30_alpha</item>
    <item name="enabledMenuIconColor">@Android:color/white</item>
1
ExpensiveBelly

Si menu visible

menu.findItem(R.id.id_name).setVisible(true);

Si masquer le menu

menu.findItem(R.id.id_name).setVisible(false);
0
murugan mani
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    // getMenuInflater().inflate(R.menu.home, menu);
    return false;
}
0
user3913975