Réponses:
Quoi qu'il en soit, la documentation couvre toutes les choses.
Une fois l'activité créée, la
onCreateOptionsMenu()
méthode n'est appelée qu'une seule fois, comme décrit ci-dessus. Le système conserve et réutilise le queMenu
vous définissez dans cette méthode jusqu'à ce que votre activité soit détruite. Si vous souhaitez modifier le menu Options à tout moment après sa création, vous devez remplacer laonPrepareOptionsMenu()
méthode. Cela vous passe l'objet Menu tel qu'il existe actuellement. Ceci est utile si vous souhaitez supprimer, ajouter, désactiver ou activer des éléments de menu en fonction de l'é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 supérieur, le menu d'options est considéré comme toujours ouvert lorsque les éléments de menu sont présentés dans la barre d'actions. 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()
.
false
pour désactiver complètement le menu.
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 FONCTION aussi désactivée:
@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);
}
}
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);
}
onPrepareOptionsMenu
?
simplifier la version @Vikas
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
Comment mettre à jour le menu actuel afin d'activer ou de désactiver les éléments lorsqu'une AsyncTask est effectuée.
Dans mon cas d'utilisation, je devais désactiver mon menu pendant que mon AsyncTask chargeait des données, puis après avoir chargé toutes les données, je devais réactiver tout le menu afin de permettre à l'utilisateur de l'utiliser.
Cela a empêché l'application de permettre aux utilisateurs de cliquer sur les éléments de menu pendant le chargement des données.
Tout d'abord, 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.
Ensuite, dans mon onCreateOptionsMenu()
je vérifie cette variable, si c'est 1 je désactive tous mes articles, sinon, je les montre simplement
@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é démarre, elle onCreateOptionsMenu()
ne sera appelée qu'une seule fois et tous mes éléments auront disparu car j'ai défini leur état au début.
Ensuite, je crée une AsyncTask où je mets cette variable d'état à 0 dans mon onPostExecute()
Cette étape est très importante!
Lorsque vous appelez, invalidateOptionsMenu();
il redémarreraonCreateOptionsMenu();
Donc, après avoir configuré 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é une fois que tout le processus asynchrone est terminé, puis mon utilisateur peut 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
}
}
la meilleure solution lorsque vous effectuez sur le tiroir de navigation
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
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>
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_id:
//Your Code....
item.setEnabled(false);
break;
}
return super.onOptionsItemSelected(item);
}
Ce que j'ai fait, c'est enregistrer une référence au menu à onCreateOptionsMenu
. Ceci est similaire à la réponse de nir sauf qu'au lieu d'enregistrer chaque élément individuel, j'ai enregistré le menu entier.
Déclarez un menu Menu toolbarMenu;
.
Ensuite, onCreateOptionsMenu
enregistrez le menu dans votre variable
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
toolbarMenu = menu;
return true;
}
Vous pouvez désormais accéder à votre menu et à tous ses éléments à tout moment.
toolbarMenu.getItem(0).setEnabled(false);
@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;
}
Si menu visible
menu.findItem(R.id.id_name).setVisible(true);
Si masquer le menu
menu.findItem(R.id.id_name).setVisible(false);
Généralement, vous pouvez modifier les propriétés de vos vues lors de l'exécution:
(Button) item = (Button) findViewById(R.id.idBut);
puis...
item.setVisibility(false)
mais
si vous souhaitez modifier la visibilité des options du ContextMenu, en appuyant sur votre bouton, vous pouvez activer un drapeau, puis dans onCreateContextMenu vous pouvez faire quelque chose comme ceci:
@Override
public void onCreateContextMenu(ContextMenu menu,
View v,ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle(R.string.context_title);
if (flagIsOn()) {
addMenuItem(menu, "Option available", true);
} else {
Toast.makeText(this, "Option not available", 500).show();
}
}
J'espère que ça aide
onCreateContextMenu
méthode. Mais je veux accéder au menu contextuel en dehors de cette méthode.
onCreateContextMenu
ne sera appelé qu'une seule fois, mais je peux cliquer sur le bouton plusieurs fois pour activer / désactiver l'élément de menu.
setEnable()
change ce qui se passe lorsque vous appuyez sur ce menu mais ne change pas son apparence (qu'est-ce qui ne va pas, développeurs Android?). Il est donc plus clair de désactiver et de modifier le titre, ou de préférence simplement de rendreMenuItem
invisible.