如何在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); } } }