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

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

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

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

27 ответов

Решение

Получить 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 { }

Я искал ответ с немного большим контекстом. Теперь, когда я понял это, я добавлю этот ответ.

Скрыть кнопку по умолчанию в меню xml

По умолчанию кнопка "Поделиться" будет скрыта, как установлено 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>

Показать кнопку в коде

Но кнопка "Поделиться" может отображаться в зависимости от некоторых условий.

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

Смотрите также

Вы можете назвать это:

MenuItem item = menu.findItem(R.id.my_item);
item.setVisible(false);

Обновить:

Убедитесь, что ваш код не возвращается null за item или это может привести к сбою приложения.

Не работал для меня Я должен был явно использовать onPrepareOptionsMenu установить элемент невидимым.

Так что используйте onCreateOptionsMenu создать меню и onPrepareOptionsMenu изменить видимость и т. д.

Изначально установите видимость пункта меню в 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);
    }
}

Попробуй это:

MenuItem myitem = menu.findItem(R.id.my_item);
myitem.setVisible(false);

Это сработало для меня как из 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);
}

Лучший способ скрыть все элементы в меню с помощью одной команды - это использовать "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 или true.

public boolean onCreateOptionsMenu(Menu menu) {
   menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible
}

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

Ответ 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);
    }
}

Согласно официальному сайту разработчика Android,OnCreateOptionMenu(меню меню) не рекомендуется для изменения пунктов меню или значков, видимости и т. Д. Во время выполнения.

После того, как система вызывает onCreateOptionsMenu(), она сохраняет экземпляр заполненного вами Меню и не будет вызывать onCreateOptionsMenu () снова, если меню по какой-то причине не будет аннулировано. Однако вы должны использовать onCreateOptionsMenu () только для создания начального состояния меню, а не для внесения изменений в течение жизненного цикла действия.

Если вы хотите изменить меню параметров на основе событий, происходящих в течение жизненного цикла действия, вы можете сделать это в методе onPrepareOptionsMenu(). Этот метод передает вам объект Menu в том виде, в котором он существует в данный момент, чтобы вы могли изменить его, например добавить, удалить или отключить элементы. (Фрагменты также обеспечивают обратный вызов onPrepareOptionsMenu().) - Официальный сайт Android Developer -

Как рекомендуется Вы можете использовать этот метод onOptionsItemSelected(элемент MenuItem) для отслеживания пользовательских вводов.

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

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

При настройке видимости всех элементов в меню, меню панели приложений или переполнение будет автоматически скрывать

пример

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

/questions/40896528/android-invalidateoptionsmenu-dlya-api-11/40896538#40896538 - ответ от Look Alterno и Sufian

  • ActivityCompat.invalidateOptionsMenu() не выполняет обратный вызов onPrepareOptionsMenu(); это просто обновить меню напрямую.
  • Мой someMethod () вызывается из нескольких мест, даже до onCreateOptionsMenu(), поэтому я должен проверить mMenu!= Null.
  • должен работать с использованием 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!= Null.

  • должен работать с использованием API 8

Android kotlin, программно скройте или установите видимость пункта меню на панели действий.

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    val inflater = menuInflater
    inflater.inflate(R.menu.main_menu, menu)
    val method = menu.findItem(R.id.menu_method)
    method.isVisible = false //if want to show set true
    return super.onCreateOptionsMenu(menu)
}

Если вы сделали все как в ответах выше, но пункт меню все еще виден, проверьте, что вы ссылаетесь на уникальный ресурс. Например, в 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 и убедитесь, что он существует только в одном файле меню. В случае, если этот ресурс уже используется где-либо и загружен в действие, он будет пытаться скрыть там.

Установить значение переменной и вызвать 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);
}

Использовать invalidateOptionsMenu()

чтобы позвонить onPrepareOptionsMenu(menu: Menu?)

вы должны использовать onCreateOptionsMenu() только для создания начального состояния меню, а не для внесения изменений во время жизненного цикла активности...

Когда происходит событие, и вы хотите выполнить обновление меню, вы должны вызвать invalidateOptionsMenu(), чтобы запросить системный вызов onPrepareOptionsMenu().

https://developer.android.com/guide/topics/ui/menus

это работает для меня; Надеюсь, это вам поможет:

      @Override
public boolean onCreateOptionsMenu(final Menu menu) {
    getMenuInflater().inflate(R.menu.my_menu_setting, menu);

    for (int i = 0; i < menu.size(); i++){
        if(menu.getItem(i).getItemId() == R.id.this_item_i_want_to_hide){
            menu.getItem(i).setVisible(false);
        }
    }

    return true;
}

Я думаю, что лучшим подходом было бы использовать переменную-член для меню, инициализировать ее в onCreateOptionsMenu() и потом просто использовать setVisible(), не аннулируя меню опций.

Этот код работал для меня

@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: Если ваши подклассы Activity ActionBarActivity, вы можете вызвать supportInvalidateOptionsMenu()

Видно здесь: /questions/31963388/kak-ya-mogu-obnovit-actionbar-kogda-onprepareoptionsmenu-pereklyuchil-punktyi-menyu/31963416#31963416

Вы пытаетесь получить доступ к пункту меню из действия, у которого нет доступа к области. Вызов для поиска пункта меню вернет null, потому что представление не связано ни с действием, ни с макетом, из которого вы вызываете.

Пункты меню связаны с такими элементами, как "Панельнавигации", которые, в свою очередь, связаны с соответствующим действием.

Поэтому инициализируйте эти представления в activity (), а затем обращайтесь к элементам меню с этими представлениями.

Navigation navView;
navView = findViewById(R.id.navigationView);

MenuItem item = navView.getMenu().findItem(R.id.item_hosting);
item.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;
}

Если вы используете панель инструментов материалов, используйте это

       var topMainToolbar = findViewById(R.id.myMaterialToolbar)
 val menuItem:MenuItem = topMainToolbar.menu.findItem(R.id.yourmenuItemId)
 menuItem.setVisible(false)

Создайте параметры меню обычным способом, см. Приведенный ниже код и добавьте глобальную ссылку внутри класса в меню

      Menu mMenu;  // global reference within the class
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_tcktdetails, menu);
    mMenu=menu;  // assign the menu to the new menu item you just created 
    return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_cancelticket) {
        cancelTicket();

        return true;
    }

    return super.onOptionsItemSelected(item);
}

Теперь вы можете переключать свое меню, запустив этот код с помощью кнопки или внутри функции.

      if(mMenu != null) {
                mMenu.findItem(R.id.action_cancelticket).setVisible(false);
            }
Другие вопросы по тегам