Как скрыть пункт меню на панели действий?
У меня есть панель действий с пунктом меню. Как я могу скрыть / показать этот пункт меню?
Вот что я пытаюсь сделать:
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);
}
}
В моем примере я спрятал все предметы.
Да.
- Вы можете установить флаг / условие.
- Вызов
invalidateOptionsMenu()
когда вы хотите скрыть опцию. Это позвонитonCreateOptionsMenu()
, - В
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;
}
Смотрите также
- Настройка панели приложения (Android-документы для помощи в настройке приложения / панели действий)
Вы можете назвать это:
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().
это работает для меня; Надеюсь, это вам поможет:
@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()
Вы пытаетесь получить доступ к пункту меню из действия, у которого нет доступа к области. Вызов для поиска пункта меню вернет 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);
}