Как я могу обновить панель действий, когда onPrepareOptionsMenu переключил пункты меню?
в моих приложениях я часто включаю / отключаю пункты меню и делаю их видимыми из onPrepareOptionsMenu.
сегодня я начал добавлять атрибут меню android: showAsAction к некоторым из моих Android 2.x приложения для отображения элементов меню, используемых наиболее На панели действий.
панель действий не отражает включение/выключение и видимость сразу. Мне нужно нажать на выпадающее меню справа, чтобы увидеть это изменение произошло.
хорошо, я понимаю, что меню пожары onPrepareOptionsMenu. Но что мне нужно сделать, чтобы обновить панель действий? Я думаю, что это изменение должно быть применено изнутри 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);
}
EDIT: если я добавлю invalidateOptionsMenu это работает на Android 3.x приложений, но падает на Android 2.X устройств из-за отсутствующего метода. Каков рекомендуемый способ сделать это правильно?
10 ответов:
мой метод выбора заключается в создании вспомогательного класса. Например:
class VersionHelper { static void refreshActionBarMenu(Activity activity) { activity.invalidateOptionsMenu(); } }
Теперь в вашем коде выше, заменить
invalidateOptionsMenu();
С:if (Build.VERSION.SDK_INT >= 11) { VersionHelper.refreshActionBarMenu(this); }
кредит для этого метода идет в CommonsWare (поиск HoneycombHelper, и проверить его книги-настоятельно рекомендуется)
Спасибо за принятый ответ. Я использую ActionBarActivity. в этом классе вы можете использовать
supportInvalidateOptionsMenu();
теперь вы можете использовать метод supportInvalidateOptionsMenu() из ActionbarActivity с библиотекой поддержки. Поэтому вам не нужно проверять версию 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" выше. Я использую его подменю. Это работает для меня :
// 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);
Я не уверен, что вы это уже видели, но если вы широко используете actionbar и планируете поддерживать более низкие API (>8), взгляните на библиотеку actionBarSherlock. Это сделает его так, что вам не придется разделять свой код actionBar для более низких и более высоких API, а затем вы можете просто запустить:
runOnUiThread(new Runnable(){ @Override public void run(){ supportInvalidateOptionsMenu(); } });
Слава @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");
вскоре после того, как вы обновили свое меню.
у меня была проблема, что чертежи не будут отображаться, даже если есть место для их отображения. Как только я сделал изменение ориентации, затем появились чертежи.. ?
В Итоге:
MainActivity:
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); } } }