Odpowiedzi:
W każdym razie dokumentacja obejmuje wszystkie rzeczy.
Po utworzeniu działania
onCreateOptionsMenu()
metoda jest wywoływana tylko raz, jak opisano powyżej. System zachowuje i ponownie wykorzystujeMenu
zdefiniowane w tej metodzie wartości, dopóki Twoja aktywność nie zostanie zniszczona. Jeśli chcesz zmienić menu opcji w dowolnym momencie po jego pierwszym utworzeniu, musisz nadpisaćonPrepareOptionsMenu()
metodę. Spowoduje to przekazanie obiektu Menu w takiej postaci, w jakiej obecnie istnieje. Jest to przydatne, jeśli chcesz usunąć, dodać, wyłączyć lub włączyć elementy menu w zależności od bieżącego stanu aplikacji.
Na przykład
@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 nowszych menu opcji jest uważane za zawsze otwarte, gdy elementy menu są prezentowane na pasku akcji. Gdy wystąpi zdarzenie i chcesz wykonać aktualizację menu, musisz zadzwonić, invalidateOptionsMenu()
aby zażądać wywołania systemowego onPrepareOptionsMenu()
.
false
aby całkowicie wyłączyć menu.
We wszystkich wersjach Androida najprostszy sposób: użyj tego, aby POKAZYĆ ikonę akcji menu jako wyłączoną ORAZ sprawić, by działała również 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);
}
}
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);
}
onPrepareOptionsMenu
?
uprościć wersję @Vikas
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
Jak zaktualizować bieżące menu, aby włączyć lub wyłączyć elementy po zakończeniu AsyncTask.
W moim przypadku musiałem wyłączyć moje menu, gdy mój AsyncTask ładował dane, a następnie po załadowaniu wszystkich danych musiałem ponownie włączyć całe menu, aby użytkownik mógł z niego korzystać.
Uniemożliwiło to aplikacji umożliwienie użytkownikom klikania elementów menu podczas ładowania danych.
Najpierw deklaruję zmienną stanu, jeśli zmienna ma wartość 0, menu jest wyświetlane, jeśli ta zmienna ma wartość 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 elementy, jeśli nie, po prostu je wszystkie pokazuję
@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, gdy rozpocznie się moja aktywność, onCreateOptionsMenu()
zostanie wywołana tylko raz, a wszystkie moje elementy znikną, ponieważ ustawiłem dla nich stan na początku.
Następnie tworzę AsyncTask, w którym ustawiam tę zmienną stanu na 0 w pliku onPostExecute()
Ten krok jest bardzo ważny!
Kiedy zadzwonisz invalidateOptionsMenu();
, uruchomi się ponownieonCreateOptionsMenu();
Tak więc, po ustawieniu mojego stanu na 0, po prostu przerysowuję całe menu, ale tym razem z moją zmienną na 0, co oznacza, że całe menu zostanie wyświetlone po zakończeniu 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
}
}
najlepsze rozwiązanie, gdy grasz w szufladzie nawigacji
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
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>
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_id:
//Your Code....
item.setEnabled(false);
break;
}
return super.onOptionsItemSelected(item);
}
Zapisałem odniesienie do menu pod adresem 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 onCreateOptionsMenu
zapisz menu do swojej 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 w dowolnym momencie.
toolbarMenu.getItem(0).setEnabled(false);
@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;
}
Jeśli widoczne menu
menu.findItem(R.id.id_name).setVisible(true);
Jeśli ukryj menu
menu.findItem(R.id.id_name).setVisible(false);
Ogólnie można zmienić właściwości widoków w czasie wykonywania:
(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
onCreateContextMenu
metodzie. Ale chcę uzyskać dostęp do menu kontekstowego poza tą metodą.
onCreateContextMenu
zostanie wywołana tylko raz, ale mogę klikać przycisk dużo czasu, aby włączyć / wyłączyć element menu.
setEnable()
zmienia to, co się dzieje po naciśnięciu tego menu, ale nie zmienia jego wyglądu (co jest nie tak, programiści Androida?). Dlatego łatwiej jest wyłączyć i zmienić tytuł, a najlepiej po prostu uczynić goMenuItem
niewidzialnym.