Comment puis-je actualiser la barre d’action lorsque onPrepareOptionsMenu a changé de menu?

Dans mes applications, j’active / désactive souvent les entrées de menu et les rend visibles depuis onPrepareOptionsMenu.

Aujourd’hui, j’ai commencé à append l’atsortingbut de menu android: showAsAction à certaines de mes applications Android 2.x pour afficher les entrées de menu les plus utilisées sur la barre d’action.

ActionBar ne reflète pas l’activation / désactivation et la visibilité immédiatement. Je dois cliquer sur le menu déroulant à droite pour voir ce changement se produire.

Ok, je comprends que le menu se déclenche surPrepareOptionsMenu. Mais que dois-je faire pour rafraîchir la barre d’action? Je pense que ce changement doit être appliqué depuis onOptionsItemSelected mais je ne sais pas ce que je devrais appeler.

Voilà le menu:

  

Voici le onPrepareOptionsMenu:

 @Override public boolean onPrepareOptionsMenu(final Menu menu) { MenuItem menuItemMapView = menu.findItem(R.id.men_mapview); MenuItem menuItemSatelliteView = menu.findItem(R.id.men_satelliteview); if (mapView.isSatellite()) { menuItemMapView.setEnabled(true).setVisible(true); menuItemmenuItemSatelliteView.setEnabled(false).setVisible(false); } else { menuItemMapView.setEnabled(false).setVisible(false); menuItemmenuItemSatelliteView.setEnabled(true).setVisible(true); } return super.onPrepareOptionsMenu(menu); } 

Voici le onOptionsItemSelected

 @Override public boolean onOptionsItemSelected(final MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.men_mapview: mapView.setSatellite(false); mapView.setStreetView(true); mapView.invalidate(); invalidateOptionsMenu(); // This works on Android 3.x devices only return true; case R.id.men_satelliteview: mapView.setSatellite(true); mapView.setStreetView(false); mapView.invalidate(); invalidateOptionsMenu(); // This works on Android 3.x devices only return true; } return super.onOptionsItemSelected(menuItem); } 

EDIT: Si j’ajoute le paramètre invalidateOptionsMenu, cela fonctionne sur les applications Android 3.x mais se bloque sur les appareils Android 2.x en raison d’une méthode manquante. Quelle est la manière recommandée de le faire correctement?

Ma méthode de choix est de créer une classe d’assistance. Par exemple:

 class VersionHelper { static void refreshActionBarMenu(Activity activity) { activity.invalidateOptionsMenu(); } } 

Maintenant, dans votre code ci-dessus, remplacez invalidateOptionsMenu(); avec:

 if (Build.VERSION.SDK_INT >= 11) { VersionHelper.refreshActionBarMenu(this); } 

Le crédit pour cette méthode va à CommonsWare (recherche de HoneycombHelper et extrait ses livres – fortement recommandé)

Merci à la réponse acceptée. J’utilise ActionBarActivity. dans cette classe, vous pouvez utiliser

 supportInvalidateOptionsMenu(); 

Utilisation

 ActivityCompat.invalidateOptionsMenu(Activity activity) 

à partir de la bibliothèque de compatibilité .

Voir: https://stackoverflow.com/a/14748687/435855

enregistrer une référence au menu et appeler:

 this.menu.clear(); this.onCreateOptionsMenu(this.menu); 

Vous pouvez maintenant utiliser la méthode supportInvalidateOptionsMenu () depuis ActionbarActivity avec la bibliothèque de support. Vous n’avez donc pas besoin de vérifier la version du SDK. Va jusqu’à l’API 7 et supérieur.

http://developer.android.com/reference/android/support/v7/app/ActionBarActivity.html

pour ce faire, vous devez importer la v7 de la bibliothèque de support en utilisant cette

http://developer.android.com/tools/support-library/setup.html

Basé sur “Klaasvaak” réponse ci-dessus. J’utilise son sous-menu. Cela fonctionne pour moi:

 // Declare and save the menu as global, so it can be called anywhere. Menu absTopSubMenus; public boolean onCreateOptionsMenu(Menu menu) { absTopSubMenus = menu; // Used for re-drawing this menu anywhere in the codes. // The remainder of your code below } 

Ensuite, pour re-dessiner ceci, appelez simplement:

 // Redraw the top sub-menu absTopSubMenus.clear(); onCreateOptionsMenu(absTopSubMenus); 

Je ne suis pas sûr que vous l’ayez déjà vu, mais si vous utilisez la barre d’action de manière approfondie et envisagez de prendre en charge les API les plus basses (> 8), consultez la bibliothèque actionBarSherlock. Il fera en sorte que vous ne devez pas sectionner votre code actionBar pour les API inférieures et supérieures, et puis vous pouvez simplement exécuter:

 runOnUiThread(new Runnable(){ @Override public void run(){ supportInvalidateOptionsMenu(); } }); 

getActivity (). invalidateOptionsMenu ();

fait le travail

Bravo à @Klaasvaak pour nous avoir montré le chemin ici. J’utilise les éléments suivants qui fonctionnent à la fois avant et après le niveau 11 de l’API:

 private void invalidOptionsMenuHelper() { if (Build.VERSION.SDK_INT >= 11) { invalidateOptionsMenu(); } else if (mOptionsMenu != null) { mOptionsMenu.clear(); onCreateOptionsMenu(mOptionsMenu); } } 

Bien sûr, vous devez enregistrer une référence au menu (mOptionsMenu dans ce cas) que j’accomplis via:

 @Override public boolean onCreateOptionsMenu(Menu menu) { mOptionsMenu = menu; //... create and manage the menu normally } 

Assurez-vous également de ne pas appeler

 myAppCompatActivity.setToolbarTitle("some dynamic title"); 

peu de temps après avoir rafraîchi votre menu.

J’avais le problème que les tirables ne seraient pas affichés même s’il y avait de la place pour les afficher. Une fois que j’ai fait une orientation changer les tirables sont alors apparus ..?

En résumé:

Activité principale:

 public class MainActivity extends AppCompatActivity { private boolean showMenu = true; public void setShowMenu(boolean show) { showMenu = show; supportInvalidateOptionsMenu(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.my_menu, menu); menu.findItem(R.id.menu_share).setVisible(showMenu); // menu.findItem(... return true; } } 

FragmentNoMenu:

 public abstract class FragmentNoMenu extends Fragment { protected MainActivity mainActivity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mainActivity = (MainActivity) getActivity(); if (mainActivity != null) { mainActivity.setShowMenu(false); } } } 

FragmentWithMenu:

 public abstract class FragmentWithMenu extends Fragment { protected MainActivity mainActivity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mainActivity = (MainActivity) getActivity(); if (mainActivity != null) { mainActivity.setShowMenu(true); } } }