Within my apps I often enable/disable menu entries and do make them visible from onPrepareOptionsMenu.
Today I started to add the android:showAsAction menu attribute to some of my Android 2.x apps to show menu entries used most on the ActionBar.
The ActionBar does not reflect the enable/disable and visibility immediately. I need to click on the menu dropdown on the right to see this change happen.
Ok, I do understand that the menu fires onPrepareOptionsMenu. But what do I need to do to refresh the ActionBar? I think this change needs to be applied from within onOptionsItemSelected but I don't know what I should call.
Here's the menu:
<item android:icon="@drawable/ic_menu_mapmode" android:id="@+id/men_mapview" android:showAsAction="ifRoom|withText" android:title="@string/txt_mapview" /> <item android:icon="@drawable/ic_menu_mapmode" android:id="@+id/men_satelliteview" android:showAsAction="ifRoom|withText" android:title="@string/txt_satelliteview" />
Here's the 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); }
Here's the 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: If I add invalidateOptionsMenu this works on Android 3.x apps but crashes on Android 2.x devices because of a missing method. What's the recommended way to do it right?
The best way to hide all items in a menu with just one command is to use "group" on your menu xml. Just add all menu items that will be in your overflow menu inside the same group. Then, on your activity (preferable at onCreateOptionsMenu), use command setGroupVisible to set all menu items visibility to false or true.
invalidateOptionsMenu() is used to say Android, that contents of menu have changed, and menu should be redrawn. For example, you click a button which adds another menu item at runtime, or hides menu items group. In this case you should call invalidateOptionsMenu() , so that the system could redraw it on UI.
To add actions to the action bar, create a new XML file in your project's res/menu/ directory. The app:showAsAction attribute specifies whether the action should be shown as a button on the app bar.
My method of choice is to create a helper class. For example:
class VersionHelper { static void refreshActionBarMenu(Activity activity) { activity.invalidateOptionsMenu(); } }
Now in your code above, replace invalidateOptionsMenu();
with:
if (Build.VERSION.SDK_INT >= 11) { VersionHelper.refreshActionBarMenu(this); }
Credit for this method goes to CommonsWare (search for HoneycombHelper, and check out his books - highly recommended)
Thanks to the accepted answer. I am using ActionBarActivity. in this class you can use
supportInvalidateOptionsMenu();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With