Android: Как включить / отключить пункт меню опции по нажатию кнопки? - PullRequest
114 голосов
/ 26 марта 2011

Я легко могу сделать это, когда использую методы onCreateOptionsMenu или onOptionsItemSelected.

Но у меня есть кнопка где-то на экране, и при нажатии этой кнопки она должна включать / отключать пункты контекстного меню..

Ответы [ 11 ]

251 голосов
/ 26 марта 2011

В любом случае, документация охватывает все вещи.

Изменение пунктов меню во время выполнения

После создания действия метод onCreateOptionsMenu()вызывается только один раз, как описано выше.Система сохраняет и повторно использует Menu, определенный вами в этом методе, до тех пор, пока ваша деятельность не будет уничтожена.Если вы хотите изменить меню параметров в любое время после его первого создания, вы должны переопределить метод onPrepareOptionsMenu().Это передает вам объект меню, как он существует в настоящее время.Это полезно, если вы хотите удалить, добавить, отключить или включить пункты меню в зависимости от текущего состояния вашего приложения.

Например

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    if (isFinalized) {
        menu.getItem(1).setEnabled(false);
        // You can also use something like:
        // menu.findItem(R.id.example_foobar).setEnabled(false);
    }
    return true;
}

На Android 3.0и выше, меню опций считается всегда открытым, когда элементы меню представлены на панели действий.Когда происходит событие, и вы хотите выполнить обновление меню, вы должны позвонить invalidateOptionsMenu(), чтобы запросить системный вызов onPrepareOptionsMenu().

59 голосов
/ 17 октября 2013

Во всех версиях Android самый простой способ: используйте это, чтобы ПОКАЗАТЬ значок действия меню как отключенный и сделать его ФУНКЦИЕЙ как отключенный:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

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

    if (myItemShouldBeEnabled) {
        item.setEnabled(true);
        item.getIcon().setAlpha(255);
    } else {
        // disabled
        item.setEnabled(false);
        item.getIcon().setAlpha(130);
    }
}
39 голосов
/ 06 июня 2012

Вы можете сохранить элемент как переменную при создании меню параметров, а затем изменить его свойства по желанию.

private MenuItem securedConnection;
private MenuItem insecuredConnection;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.connect_menu, menu);
    securedConnection = menu.getItem(0);
    insecuredConnection =  menu.getItem(1);
    return true;
}

public void foo(){
       securedConnection.setEnabled(true);
}    
5 голосов
/ 10 сентября 2016

упрощенная версия @Vikas

@Override
public boolean onPrepareOptionsMenu (Menu menu) {

    menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
    return true;
}
2 голосов
/ 16 ноября 2018

Как обновить текущее меню, чтобы включить или отключить элементы, когда AsyncTask сделан.

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

Это не позволило приложению позволить пользователям нажимать на пункты меню во время загрузки данных.

Во-первых,Я объявляю переменную состояния, если переменная равна 0, отображается меню, если эта переменная равна 1, меню скрыто.

private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.

Затем в моем onCreateOptionsMenu() я проверяю эту переменную, если она равна 1Я отключаю все свои предметы, если нет, я просто показываю их все

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);

        if(mMenuState==1){
            for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(false);
            }
        }else{
             for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(true);
            }
        }

        return super.onCreateOptionsMenu(menu);
    }

Теперь, когда моя активность начнется, onCreateOptionsMenu() будет вызван только один раз, и все мои вещи исчезнут, потому что я настроилсостояние для них в начале.

Затем я создаю AsyncTask, где я устанавливаю эту переменную состояния в 0 в моем onPostExecute()

Этот шаг очень важен!

Когда вы звоните invalidateOptionsMenu();, это будетunch onCreateOptionsMenu();

Итак, после установки моего состояния в 0, я просто перерисовываю все меню, но на этот раз с моей переменной на 0, что говорит о том, что все меню будет отображаться после того, как весь асинхронный процессГотово, и затем мой пользователь может использовать меню.

 public class LoadMyGroups extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration. 

        }

        @Override
        protected Void doInBackground(Void... voids) {
           //Background work

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
            invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu

        }
    }

Результаты

enter image description here

2 голосов
/ 25 ноября 2015

лучшее решение, когда вы работаете на навигационном ящике

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.setGroupVisible(0,false);
        return true;
    }
1 голос
/ 11 октября 2018
  @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            switch (item.getItemId()) {

                case R.id.item_id:

                       //Your Code....

                        item.setEnabled(false);
                        break;
              }
            return super.onOptionsItemSelected(item);
     }
0 голосов
/ 13 июля 2019

Более современный ответ на старый вопрос:

MainActivity.kt

private var myMenuIconEnabled by Delegates.observable(true) { _, old, new ->
    if (new != old) invalidateOptionsMenu()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    findViewById<Button>(R.id.my_button).setOnClickListener { myMenuIconEnabled = false }
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu_main_activity, menu)
    return super.onCreateOptionsMenu(menu)
}

override fun onPrepareOptionsMenu(menu: Menu): Boolean {
    menu.findItem(R.id.action_my_action).isEnabled = myMenuIconEnabled
    return super.onPrepareOptionsMenu(menu)
}

menu_main_activity.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">
<item
    android:id="@+id/action_my_action"
    android:icon="@drawable/ic_my_icon_24dp"
    app:iconTint="@drawable/menu_item_icon_selector"
    android:title="My title"
    app:showAsAction="always" />
</menu>

menu_item_icon_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?enabledMenuIconColor" android:state_enabled="true" />
<item android:color="?disabledMenuIconColor" />

attrs.xml

<resources>   
    <attr name="enabledMenuIconColor" format="reference|color"/>
    <attr name="disabledMenuIconColor" format="reference|color"/>
</resources>

styles.xml or themes.xml

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="disabledMenuIconColor">@color/white_30_alpha</item>
    <item name="enabledMenuIconColor">@android:color/white</item>
0 голосов
/ 21 февраля 2019

Если отображается меню

menu.findItem(R.id.id_name).setVisible(true);

Если скрыть меню

menu.findItem(R.id.id_name).setVisible(false);
0 голосов
/ 03 октября 2018
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    // getMenuInflater().inflate(R.menu.home, menu);
    return false;
}
...