Android: jak włączyć / wyłączyć opcję menu po kliknięciu przycisku?

Mogę to łatwo zrobić, gdy używam metod onCreateOptionsMenu LUB onOptionsItemSelected.

Ale mam przycisk gdzieś na ekranie i po kliknięciu tego przycisku powinien włączyć / wyłączyć pozycje menu kontekstowego.

Author: Janusz, 2011-03-26

12 answers

W każdym razie, dokumentacja obejmuje wszystkie rzeczy.

Zmiana pozycji menu w czasie wykonywania

Po utworzeniu aktywności, onCreateOptionsMenu() metoda nazywa się tylko raz, jak opisano powyżej. Na system utrzymuje i ponownie wykorzystuje Menu TY zdefiniuj w tej metodzie aż do aktywność jest zniszczona. Jeśli chcesz Zmień menu opcji w dowolnym momencie po jest najpierw utworzony, musisz nadpisać Metoda onPrepareOptionsMenu(). To przekazuje Ci obiekt Menu, jak to obecnie istnieje. Jest to przydatne, jeśli chcesz usunąć, dodać, wyłączyć lub włącz pozycje menu w zależności od aktualny stan aplikacji.

Np.

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

W systemie Android 3.0 i nowszym menu Opcje jest zawsze otwarte, gdy elementy menu są prezentowane na pasku akcji. Gdy wystąpi zdarzenie i chcesz wykonać aktualizację menu, musisz wywołać invalidateOptionsMenu(), aby zażądać wywołania systemowego onPrepareOptionsMenu().

 278
Author: Vikas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-01 17:28:24

We wszystkich wersjach Androida, najprostszy sposób: użyj tego, aby wyświetlić ikonę akcji menu jako wyłączoną i sprawić, że będzie ona również działać jako Wyłączona:

@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);
    }
}
 67
Author: Frank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-17 08:28:39

Możesz zapisać element jako zmienną podczas tworzenia menu opcji, a następnie dowolnie zmieniać jego właściwości.

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);
}    
 42
Author: nir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 09:08:30

Simplify @ Vikas version

@Override
public boolean onPrepareOptionsMenu (Menu menu) {

    menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
    return true;
}
 6
Author: Kosrat D. Ahmad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-10 20:18:20

Jak zaktualizować bieżące menu, aby włączyć lub wyłączyć elementy po wykonaniu zadania asynchronicznego.

W moim przypadku użycia musiałem wyłączyć Moje menu podczas gdy mój AsyncTask ładował dane, a następnie po załadowaniu wszystkich danych, musiałem ponownie włączyć wszystkie menu, aby umożliwić użytkownikowi korzystanie z niego.

Uniemożliwiło to aplikacji pozwalanie użytkownikom na klikanie pozycji menu podczas ładowania danych.

Najpierw deklaruję zmienną stanową, jeśli zmienna ma wartość 0 to wyświetla się menu, jeśli zmienna jest 1 menu jest ukryte.

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

Następnie w moim onCreateOptionsMenu() sprawdzam tę zmienną, jeśli jest 1 wyłączam wszystkie moje pozycje, jeśli nie, po prostu pokazuję je wszystkie

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

Teraz, Kiedy moja aktywność się rozpocznie, onCreateOptionsMenu() zostanie wywołana tylko raz, a wszystkie moje przedmioty znikną, ponieważ ustawiłem dla nich stan na początku.

Następnie tworzę AsyncTask gdzie ustawiam zmienną stanową na 0 w moim onPostExecute()

Ten krok jest bardzo ważny!

Kiedy zadzwonisz invalidateOptionsMenu(); to uruchomi się ponownie onCreateOptionsMenu();

Tak więc, po ustawieniu mojego stanu na 0, po prostu przerysowałem wszystkie menu, ale tym razem z moją zmienną na 0, to powiedziawszy, wszystkie menu będzie wyświetlane po wykonaniu całego procesu asynchronicznego, a następnie mój użytkownik może korzystać z menu.

 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

        }
    }

Wyniki

Tutaj wpisz opis obrazka

 6
Author: Gastón Saillén,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-20 22:43:06

Najlepsze rozwiązanie gdy jesteś wykonywany na szufladzie nawigacyjnej

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.setGroupVisible(0,false);
        return true;
    }
 2
Author: Prashant Gosai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-25 06:58:36

If visible menu

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

If hide menu

menu.findItem(R.id.id_name).setVisible(false);
 2
Author: murugan mani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-22 05:18:50

Bardziej nowoczesna odpowiedź na Stare pytanie:

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>
 2
Author: ExpensiveBelly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-12 21:29:11

Zapisałem odwołanie do Menu w onCreateOptionsMenu. Jest to podobne do odpowiedzi nir, z tym, że zamiast zapisywać każdą pojedynczą pozycję, zapisałem całe menu.

Zadeklaruj Menu Menu toolbarMenu;.

Następnie w onCreateOptionsMenu Zapisz menu do zmiennej

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    getMenuInflater().inflate(R.menu.main_menu, menu);
    toolbarMenu = menu;
    return true;
}

Teraz możesz uzyskać dostęp do swojego menu i wszystkich jego pozycji, kiedy tylko chcesz. toolbarMenu.getItem(0).setEnabled(false);

 2
Author: Smitty-Werben-Jager-Manjenson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-05 21:51:44
  @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            switch (item.getItemId()) {

                case R.id.item_id:

                       //Your Code....

                        item.setEnabled(false);
                        break;
              }
            return super.onOptionsItemSelected(item);
     }
 1
Author: Tousif Akram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-11 06:10:34
@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;
}
 0
Author: Draken,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 12:41:17

Ogólnie można zmienić właściwości swoich widoków w runtime:

(Button) item = (Button) findViewById(R.id.idBut);
I wtedy...
item.setVisibility(false)

Ale

Jeśli chcesz zmodyfikować widoczność opcji z ContextMenu, po naciśnięciu przycisku możesz aktywować flagę, a następnie w onCreateContextMenu możesz zrobić coś takiego:

 @Override
        public void onCreateContextMenu(ContextMenu menu, 
                View v,ContextMenu.ContextMenuInfo menuInfo) {

            super.onCreateContextMenu(menu, v, menuInfo);

                menu.setHeaderTitle(R.string.context_title);

                if (flagIsOn()) {
                    addMenuItem(menu, "Option available", true);
                } else {
                    Toast.makeText(this, "Option not available", 500).show();
                }

        }

Mam nadzieję, że to pomoże

 -4
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-20 10:46:09