Как скрыть пункт меню в панели действий?


У меня есть панель действий с меню. Как я могу Скрыть/показать пункт меню?

вот что я пытаюсь сделать:

MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
20 272

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

в моем примере я скрыл все элементы.

да.

  1. вы можете установить флаг/состояние.
  2. вызов invalidateOptionsMenu() когда вы хотите скрыть. Это вызовет onCreateOptionsMenu().
  3. на 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".

enter image description here

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 может быть дополнительно показана на основе некоторых состояние.

enter image description here

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

см. также

не работает для меня. Я должен был явно использовать 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

можно использовать toolbar.getMenu().clear(); скрыть все пункты меню одновременно

Если вы сделали все, как в приведенных выше ответах, но пункт меню все еще виден, проверьте, что вы ссылаетесь на уникальный ресурсов. Например, в 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;
}