Как скрыть пункт меню в actionbar?

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

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

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) получить ссылку на MenuItem (по телефону 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 изменить видимость etc.


это сработало для меня как от активности, так и от фрагмента

@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(), так что я должен проверить мрнению != недействительный.
  • должен работать с использованием 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(), так что я должен проверить мрнению != недействительный.

  • должен работать с помощью 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 + щелчок R. id.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() после этого, не делая недействительным меню опций.


лучший способ скрыть все элементы в меню с помощью одной команды-использовать" group " в меню 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 и всегда проверяйте, если menu равно 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;
}