Как скрыть пункт меню в панели действий?
У меня есть панель действий с меню. Как я могу Скрыть/показать пункт меню?
вот что я пытаюсь сделать:
MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
20 ответов:
получить
MenuItem
указывая на такие позиции, называютsetVisible
на нем настроить его видимость, а затем позвонитьinvalidateOptionsMenu()
на вашей деятельности, так что меню ActionBar настраивается соответствующим образом.обновление: A
MenuItem
это не обычный вид, который является частью вашего макета. Это что-то особенное, совершенно другое. Ваш код возвращаетnull
наitem
и это вызывает крах. Вместо этого вам нужно сделать:MenuItem item = menu.findItem(R.id.addAction);
вот последовательность : первый звонок
invalidateOptionsMenu()
иonCreateOptionsMenu(Menu)
получить ссылку на меню (по телефонуmenu.findItem()
) и вызовsetVisible()
на
нашел добавление к этому вопросу:
Если вы хотите изменить видимость пунктов меню на ходу, вам просто нужно установить переменную-член в своей деятельности помнить, что вы хотите скрыть меню и вызов
invalidateOptionsMenu()
и скрыть элементы в переопределенномonCreateOptionsMenu(...)
метод.//anywhere in your code ... mState = HIDE_MENU; // setting state invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again ... @Override public boolean onCreateOptionsMenu(Menu menu) { // inflate menu from xml MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.settings, menu); if (mState == HIDE_MENU) { for (int i = 0; i < menu.size(); i++) menu.getItem(i).setVisible(false); } }
в моем примере я скрыл все элементы.
да.
- вы можете установить флаг/состояние.
- вызов
invalidateOptionsMenu()
когда вы хотите скрыть. Это вызоветonCreateOptionsMenu()
.- на
onCreateOptionsMenu()
, проверьте флаг / условие и показать или спрячьте его следующим образом:MenuItem item = menu.findItem(R.id.menu_Done); if (flag/condition)) { item.setVisible(false); } else { }
вы можете назвать это:
MenuItem item = menu.findItem(R.id.my_item); item.setVisible(false);
обновление:
убедитесь, что ваш код не возвращает
null
наitem
или это может привести к сбою приложения.
Я искал ответ с немного большим контекстом. Теперь, когда я понял это, я добавлю этот ответ.
кнопка скрыть по умолчанию в меню xml
по умолчанию кнопка share будет скрыта, как установлено
android:visible="false"
.main_menu.xml
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- hide share button by default --> <item android:id="@+id/menu_action_share" android:icon="@drawable/ic_share_white_24dp" android:visible="false" android:title="Share" app:showAsAction="always"/> <item android:id="@+id/menu_action_settings" android:icon="@drawable/ic_settings_white_24dp" android:title="Setting" app:showAsAction="ifRoom"/> </menu>
показать кнопку в коде
но кнопка share может быть дополнительно показана на основе некоторых состояние.
MainActivity.java
public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_menu, menu); MenuItem shareItem = menu.findItem(R.id.menu_action_share); // show the button when some condition is true if (someCondition) { shareItem.setVisible(true); } return true; }
см. также
- настройка Панели приложений (Android docs для получения справки о настройке панели приложений / действий)
не работает для меня. Я должен был явно использовать
onPrepareOptionsMenu
для установки невидимого элемента.чтобы использовать
onCreateOptionsMenu
для создания меню иonPrepareOptionsMenu
изменить видимость и т. д.
это сработало для меня как из Activity, так и из Fragment
@Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); if (menu.findItem(R.id.action_messages) != null) menu.findItem(R.id.action_messages).setVisible(false); }
первоначально установите видимость пункта меню в false в файле макета меню следующим образом:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:visible="false" android:id="@+id/action_do_something" android:title="@string/txt_do_something" app:showAsAction="always|withText" android:icon="@drawable/ic_done"/> </menu>
затем вы можете просто установить видимость пункта меню в false в вашем onCreateOptionsMenu () после раздувания меню.
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(menu,R.menu.menu); MenuItem item = menu.findItem(R.id.menuItemId); if (item != null){ item.setVisible(false); } }
p1r4nh4 ответ работает нормально, я просто упростил его с помощью логического флага:
public int mState = 0; //at the top of the code //where you want to trigger the hide action mState = 1; // to hide or mState = 0; to show invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again ... @Override public boolean onCreateOptionsMenu(Menu menu) { // inflate menu from xml MenuInflater inflater = getSupportMenuInflater(); inflater.inflate(R.menu.settings, menu); if (mState == 1) //1 is true, 0 is false { //hide only option 2 menu.getItem(2).setVisible(false); } }
установите значение переменной и вызовите invalidateOptionsMenu ();
selectedid=arg2; invalidateOptionsMenu(); public boolean onPrepareOptionsMenu(Menu menu) { if(selectedid==1){ menu.findItem(R.id.action_setting).setVisible(false); menu.findItem(R.id.action_s2).setVisible(false); menu.findItem(R.id.action_s3).setVisible(false); } else{ if(selectedid==2){ menu.findItem(R.id.action_search).setVisible(false); menu.findItem(R.id.action_s4).setVisible(false); menu.findItem(R.id.action_s5).setVisible(false); } } return super.onPrepareOptionsMenu(menu); }
согласно официальному сайту разработчика Android, OnCreateOptionMenu (меню Меню) не рекомендуется для изменения пунктов меню или значков, видимости..и т. д. Во время выполнения.
после того, как система вызывает onCreateOptionsMenu (), она сохраняет экземпляр меню, которое вы заполняете, и не будет снова вызывать onCreateOptionsMenu (), если меню по какой-либо причине не будет признано недействительным. Тем не менее, вы должны использовать onCreateOptionsMenu () только для создания начального состояния меню и не делать изменения в течение жизненного цикла активности.
Если вы хотите изменить меню параметров на основе событий, которые происходят в течение жизненного цикла действия, вы можете сделать это в методе onPrepareOptionsMenu (). Этот метод передает объект меню в существующем виде, чтобы его можно было изменить, например добавить, удалить или отключить элементы. (Фрагменты также обеспечивают обратный вызов onPrepareOptionsMenu ().) --Официальный Сайт AndroidDeveloper --
Как рекомендуется вы можете используйте это onOptionsItemSelected (элемент меню) метод отслеживания пользовательских входов.
@Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.edit) { Intent intent = new Intent(this, ExampleActivity.class); intent.putExtra(BUNDLE_KEY, mConnection); startActivityForResult(intent, PICK_CHANGE_REQUEST); return true; } else if (id == R.id.delete) { showDialog(this); return true; } return super.onOptionsItemSelected(item); }
Если вам нужно изменить пункты меню во время выполнения, вы можете использовать onPrepareOptionsMenu(меню) изменить их
@Override public boolean onPrepareOptionsMenu(Menu menu){ if (Utils.checkNetworkStatus(ExampleActivity.this)) { menu.findItem(R.id.edit).setVisible(true); menu.findItem(R.id.delete).setVisible(true); }else { menu.findItem(R.id.edit).setVisible(false); menu.findItem(R.id.delete).setVisible(false); } return true; }
https://stackoverflow.com/a/21215280/466363 - ответили взглядом Альтерно и Суфиан
- ActivityCompat.invalidateOptionsMenu() не выполняет обратный вызов onPrepareOptionsMenu (); он просто обновляет меню напрямую.
- мой someMethod () вызывается из нескольких мест, даже раньше onCreateOptionsMenu (), поэтому я должен проверить mMenu != недействительный.
- должен работать с помощью API 8
.
private Menu mMenu; @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.track_fragment, menu); mMenu = menu; } ... private void someMethod() { ... if (mMenu != null) { MenuItem item = mMenu.findItem(R.id.new_track); if (item != null) { item.setVisible(false); ActivityCompat.invalidateOptionsMenu(this.getActivity()); } } ... }
ActivityCompat.invalidateOptionsMenu() не выполняет обратный вызов onPrepareOptionsMenu (); он просто обновляет меню напрямую.
мой someMethod () вызывается из нескольких мест, даже раньше onCreateOptionsMenu (), поэтому я должен проверить mMenu != недействительный.
- должен работать с помощью API 8
Если вы сделали все, как в приведенных выше ответах, но пункт меню все еще виден, проверьте, что вы ссылаетесь на уникальный ресурсов. Например, в onCreateOptionsMenu или onPrepareOptionsMenu
@Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); MenuItem menuOpen = menu.findItem(R.id.menu_open); menuOpen.setVisible(false); }
Ctrl+клик Р. ИД.menu_open и проверить, что он существует только в одном меню Файл. В случае, если этот ресурс уже используется в любом месте и загружен в действие, он попытается скрыться там.
этот код работал для меня
@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu,menu); if (Application.sharedPreferences.getInt("type",1) == 2) { menuItem = menu.findItem(R.id.menu_travel_orders); menuItem.setVisible(false); } return super.onCreateOptionsMenu(menu); }
для тех, кто использует библиотеку Appcompat: Если ваша активность подклассов ActionBarActivity, вы можете вызвать supportInvalidateOptionsMenu ()
посмотреть здесь: https://stackoverflow.com/a/19649877/1562524
Я думаю, что лучшим подходом было бы использовать переменную-член для меню, инициализировать ее в onCreateOptionsMenu() и просто использовать setVisible() впоследствии, не делая недействительным меню опций.
лучший способ скрыть все элементы в меню с помощью только одной команды, чтобы использовать "группа" в меню xml. Просто добавьте все пункты меню, которые будут в вашем меню переполнения внутри той же группы.
в этом примере у нас есть два пункта меню, которые всегда будут отображаться (обычный элемент и поиск) и три элемента переполнения:
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/someItemNotToHide1" android:title="ITEM" app:showAsAction="always" /> <item android:id="@+id/someItemNotToHide2" android:icon="@android:drawable/ic_menu_search" app:showAsAction="collapseActionView|ifRoom" app:actionViewClass="android.support.v7.widget.SearchView" android:title="Search"/> <group android:id="@+id/overFlowItemsToHide"> <item android:id="@+id/someID" android:orderInCategory="1" app:showAsAction="never" /> <item android:id="@+id/someID2" android:orderInCategory="1" app:showAsAction="never" /> <item android:id="@+id/someID3" android:orderInCategory="1" app:showAsAction="never" /> </group> </menu>
затем в вашей активности (предпочтительно в onCreateOptionsMenu) используйте команду setGroupVisible, чтобы установить все пункты меню видимость false или истинный.
public boolean onCreateOptionsMenu(Menu menu) { menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible }
Если вы хотите использовать эту команду в любом другом месте своей деятельности, обязательно сохраните класс меню в local и всегда проверяйте, является ли меню null, потому что вы можете выполнить перед createOptionsMenu:
Menu menu; public boolean onCreateOptionsMenu(Menu menu) { this.menu = menu; } public void hideMenus() { if (menu != null) menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible }
установив видимость всех элементов меню, меню Панели приложений или меню переполнения будет автоматически скрываться
пример
private Menu menu_change_language;
...
...
@Override public boolean onCreateOptionsMenu(Menu menu) { ... ... menu_change_language = menu; menu_change_language.findItem(R.id.menu_change_language) .setVisible(true); return super.onCreateOptionsMenu(menu); }
перед переходом к другому фрагменту используйте следующий код:
if(menu_change_language != null){ menu_change_language.findItem(R.id.menu_change_language) .setVisible(false); }
этот подход работал для меня:
private Menu thismenu; if (condition) { if(thismenu != null) { thismenu.findItem(R.id.menu_save).setVisible(true); Toast.makeText(ProfileActivity.this, ""+thismenu.findItem(R.id.menu_save).getTitle(), Toast.LENGTH_SHORT).show(); }else { thismenu.findItem(R.id.menu_save).setVisible(false); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.profile_menu, menu); thismenu = menu; return true; }