如何在onPrepareOptionsMenu切换菜单条目时刷新ActionBar?

在我的应用程序中,我经常启用/禁用菜单条目,并使它们从onPrepareOptionsMenu可见。

今天,我开始在我的一些Android 2.x应用程序中添加android:showAsAction菜单属性,以显示ActionBar上最常用的菜单条目。

ActionBar不立即反映启用/禁用和可见性。 我需要点击右边的菜单下拉菜单,看看发生了什么变化。

好的,我明白,菜单会触发onPrepareOptionsMenu。 但是,我需要做什么来刷新ActionBar? 我认为这个改变需要从onOptionsItemSelected内部应用,但是我不知道该怎么调用。

这里是菜单:

<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" /> 

这是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); } 

这是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); } 

编辑:如果我添加invalidateOptionsMenu这适用于Android 3.x应用程序,但由于缺less方法在Android 2.x设备上崩溃。 推荐的方法是什么?

我select的方法是创build一个辅助类。 例如:

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

现在在你的代码中,replaceinvalidateOptionsMenu(); 有:

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

这种方法的信用转到CommonsWare(searchHoneycombHelper,并检查他的书 – 强烈推荐)

感谢接受的答案。 我正在使用ActionBarActivity。 在这个类中你可以使用

 supportInvalidateOptionsMenu(); 

使用

 ActivityCompat.invalidateOptionsMenu(Activity activity) 

从兼容性库 。

请参阅: https : //stackoverflow.com/a/14748687/435855

保存对菜单的引用并调用:

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

现在可以使用支持库从ActionbarActivity中使用supportInvalidateOptionsMenu()方法。 所以你不必检查sdk的版本。 直到API 7及以上。

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

这样做,你必须使用这个导入支持库的v7

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

基于上面的“Klaasvaak”的回答。 我正在使用它的subMenus。 这适用于我:

 // 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 } 

然后,重新绘制这个,只需打电话:

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

我不确定你是否已经看到它,但是如果你广泛地使用操作栏,并计划支持较低的API(> 8),请查看actionBarSherlock库。 这将使它,所以你不必为更低和更高的API分区你的actionBar代码,然后你可以运行:

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

。getActivity()invalidateOptionsMenu();

完成工作。

荣誉@Klaasvaak向我们展示了这里的方式。 我使用以下在API级别11之前和之后的工作:

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

当然,你必须保存一个对菜单的引用(在这种情况下是mOptionsMenu)

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

还要确保你不打电话

 myAppCompatActivity.setToolbarTitle("some dynamic title"); 

在您刷新菜单后不久。

我有这样的问题,即使有空间显示,drawable也不会显示出来。 一旦我做了一个方向改变的绘图,然后出现..?

综上所述:

主要活动:

 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); } } }