2012-05-21 4 views

ответ

352

Получить MenuItem указывающей на такой пункт, вызовите setVisible на него, чтобы настроить его видимость, а затем вызвать invalidateOptionsMenu() от вашей активности, так что меню ActionBar регулируется соответственно.

Обновление: A MenuItem - это не обычный вид, который является частью вашего макета. Это нечто особенное, совершенно другое. Ваш код возвращает null для item, и это вызывает крушение. Что вам нужно, вместо того, чтобы это сделать:

MenuItem item = menu.findItem(R.id.addAction); 

Вот последовательность: первый вызов invalidateOptionsMenu(), а затем внутри onCreateOptionsMenu(Menu) получить ссылку на MenuItem (по телефону menu.findItem()) и вызовите setVisible() на него

+0

Это то, что я думал изначально, но это приводит к сбою приложения. –

+3

@Stir Zoltán: Ну, вот как вы это делаете, возможно, вы ошибетесь, если это сбой приложения. Например, ваш 'MenuItem' может быть' null', потому что вы используете 'getItem' вместо' findItem'. Мы никогда не узнаем, не увидев как ваш код, так и журнал сбоев. –

+0

Обновлен вопрос. –

32

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

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

Update:

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

65

Да.

  1. Вы можете установить флаг/условие.
  2. Позвоните по номеру invalidateOptionsMenu(), если вы хотите скрыть этот параметр. Это позвонит onCreateOptionsMenu().
  3. В onCreateOptionsMenu(), проверьте флаг/состояние и шоу или скрыть это следующим образом:
MenuItem item = menu.findItem(R.id.menu_Done); 

if (flag/condition)) { 
    item.setVisible(false); 
} else { } 
+2

это 'invalidateOptionsMenu' вместо' invalidateOptions'? – razzak

+2

Если вы сделаете свой флаг логическим, вы можете просто установить видимость элемента на флаг (или флаг!), Если это необходимо. Итак, item.setVisbility (! Flag); делает это одним лайнером без условия if. – jwehrle

120

Найдено добавление к этому вопросу:

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

Это именно то, что я искал. удерживая объект MenuItem и вызывающий setVisible(), похоже, не сделал того, что я ожидал (может быть, потому, что я вызывал invalidateOptionsMenu() после, тем самым перестраивая меню), но в любом случае - это работает точно так же, как я надеялся, спасибо! – Matt

+1

Если вы собираетесь скрыть каждый предмет, есть более простой способ. Вместо того, чтобы перебирать каждый элемент здесь, вы можете просто: 'if (HIDE_MENU) {return false; } else {getSupportMenuInflater(). inflate (меню R.menu.menu_settings, меню); return true; } 'Состояние документов:« Вы должны вернуть true для отображаемого меню, если вы вернете false, оно не будет отображаться ». – w3bshark

+0

Кроме того, я хотел бы упомянуть, что этот подход намного чище, чем принятый ответ. Спасибо, что поделился! – w3bshark

6

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

Использование '0' и' 1' не является «логическим флагом», это псевдо-логическое. кроме того, здесь нет оснований использовать фактическое логическое значение. –

+2

Кроме того, у вас может быть несколько состояний, а не только один, чтобы скрыть, а другой показать. В зависимости от сложности вашего приложения и вашего отказа от написания новых действий для новых состояний приложений у вас может быть состояние SHOW_ALL, состояние HIDE_ALL, но также состояние HIDE_EDIT или HIDE_SHARE, если вы хотите скрыть определенные части вашего меню. – P1r4nh4

5

Первоначально установить видимость пункта меню в ложна в файле макета меню следующим образом:

<?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); 
    } 
} 
+0

onCreateOptionsMenu не возвращает логическое значение. Решение отлично работало. – Joseph

20

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

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

+0

Для меня это работало в обоих направлениях, но на основе [Android-документов Android] (https://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu (android.view.Menu)) 'onPrepareOptionsMenu' кажется подходящее место для этого типа операции: «Подготовьте стандартное меню параметров экрана, которое будет отображаться. Это вызывается прямо перед отображением меню каждый раз, когда оно отображается. Вы можете использовать этот метод для эффективного включения/выключения элементов или в противном случае динамически изменять содержимое ». – yuval

2

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

https://stackoverflow.com/a/21215280/466363 - ответил Смотри Alterno и Sufian

  • ActivityCompat.invalidateOptionsMenu() не обратный вызов onPrepareOptionsMenu(); он просто обновляет меню напрямую.
  • My 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(); он просто обновляет меню напрямую.

  • My someMethod() вызывается из нескольких мест, даже до onCreateOptionsMenu(), поэтому я должен проверить mMenu! = Null.

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

Это работало для меня от обоих Деятельность и фрагмент

@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); 
} 
+1

В моем случае onPrepareOptionsMenu возвращает boolean, а не void. – CoolMind

18

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

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

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

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

Но кнопка доли необязательно может подбираться на основе некоторого условия.

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

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

  • Setting Up the App Bar (Android документы для получения помощи панели приложений/действий настроить)
+0

Это правильное решение. –

1

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

1

Если вы сделали все, как и в вышеприведенных ответов, а пункт меню остается видимым, убедитесь, что вы ссылаетесь на уникального ресурса. Например, в onCreateOptionsMenu или onPrepareOptionsMenu

@Override 
public void onPrepareOptionsMenu(Menu menu) { 
    super.onPrepareOptionsMenu(menu); 
    MenuItem menuOpen = menu.findItem(R.id.menu_open); 
    menuOpen.setVisible(false); 
} 

Ctrl + Click R.id.menu_open и убедитесь, что она существует только в одном файле меню. В случае, когда этот ресурс уже используется в любом месте и загружается в действие, он попытается скрыть его.

0

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

0

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

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

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

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

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

В Рекомендован Вы можете использовать этот 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 (меню Menu) изменить их

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

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

@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); 
} 
Смежные вопросы