Antworten:
Wie auch immer, die Dokumentation deckt alle Dinge ab.
Sobald die Aktivität erstellt wurde, wird die
onCreateOptionsMenu()
Methode wie oben beschrieben nur einmal aufgerufen. Das System behältMenu
die in dieser Methode definierten Daten bei und verwendet sie wieder , bis Ihre Aktivität zerstört ist. Wenn Sie das Optionsmenü jederzeit nach seiner ersten Erstellung ändern möchten, müssen Sie dieonPrepareOptionsMenu()
Methode überschreiben . Dadurch erhalten Sie das Menüobjekt, wie es derzeit vorhanden ist. Dies ist nützlich, wenn Sie Menüelemente je nach aktuellem Status Ihrer Anwendung entfernen, hinzufügen, deaktivieren oder aktivieren möchten.
Z.B
@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;
}
Unter Android 3.0 und höher gilt das Optionsmenü immer als geöffnet, wenn Menüelemente in der Aktionsleiste angezeigt werden. Wenn ein Ereignis auftritt und Sie eine Menüaktualisierung durchführen möchten, müssen Sie anrufen invalidateOptionsMenu()
, um den Systemaufruf anzufordern onPrepareOptionsMenu()
.
false
Kehren Sie zurück , um das Menü vollständig zu deaktivieren.
Bei allen Android-Versionen ist dies am einfachsten: Verwenden Sie diese Option, um ein Menüaktionssymbol als deaktiviert anzuzeigen und es auch als deaktiviert zu aktivieren:
@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);
}
}
Sie können das Element beim Erstellen des Optionsmenüs als Variable speichern und dann seine Eigenschaften nach Belieben ändern.
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
?
Vereinfachen Sie die @ Vikas-Version
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
So aktualisieren Sie das aktuelle Menü, um die Elemente zu aktivieren oder zu deaktivieren, wenn eine AsyncTask abgeschlossen ist.
In meinem Anwendungsfall musste ich mein Menü deaktivieren, während meine AsyncTask Daten lud. Nachdem ich alle Daten geladen hatte, musste ich das gesamte Menü erneut aktivieren, damit der Benutzer es verwenden konnte.
Dadurch wurde verhindert, dass Benutzer beim Laden von Daten auf Menüelemente klicken konnten.
Zuerst deklariere ich eine Zustandsvariable. Wenn die Variable 0 ist, wird das Menü angezeigt. Wenn diese Variable 1 ist, wird das Menü ausgeblendet.
private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.
Dann suche onCreateOptionsMenu()
ich in meiner nach dieser Variablen. Wenn es 1 ist, deaktiviere ich alle meine Elemente. Wenn nicht, zeige ich sie einfach alle an
@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);
}
Nun, wenn meine Aktivität beginnt, onCreateOptionsMenu()
wird sie nur einmal aufgerufen, und alle meine Gegenstände sind verschwunden, weil ich zu Beginn den Status für sie eingerichtet habe.
Dann erstelle ich eine AsyncTask, in der ich diese Statusvariable in meinem auf 0 setze onPostExecute()
Dieser Schritt ist sehr wichtig!
Wenn du anrufst invalidateOptionsMenu();
, wird es neu gestartetonCreateOptionsMenu();
Nachdem ich meinen Status auf 0 gesetzt habe, zeichne ich einfach das gesamte Menü neu, aber diesmal mit meiner Variablen auf 0, das heißt, das gesamte Menü wird angezeigt, nachdem der gesamte asynchrone Prozess abgeschlossen ist, und dann kann mein Benutzer das Menü verwenden .
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
}
}
Die beste Lösung, wenn Sie mit der Navigationsschublade arbeiten
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
Eine modernere Antwort auf eine alte Frage:
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);
}
Was ich getan habe, war einen Verweis auf das Menü unter zu speichern onCreateOptionsMenu
. Dies ähnelt der Antwort von nir, außer dass ich nicht jedes einzelne Element, sondern das gesamte Menü gespeichert habe.
Deklarieren Sie ein Menü Menu toolbarMenu;
.
Dann onCreateOptionsMenu
speichern Sie im Menü auf Ihre Variable
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
toolbarMenu = menu;
return true;
}
Jetzt können Sie jederzeit auf Ihr Menü und alle Elemente zugreifen.
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;
}
Wenn sichtbar Menü
menu.findItem(R.id.id_name).setVisible(true);
Wenn Menü ausblenden
menu.findItem(R.id.id_name).setVisible(false);
Im Allgemeinen können die Eigenschaften Ihrer Ansichten zur Laufzeit geändert werden:
(Button) item = (Button) findViewById(R.id.idBut);
und dann...
item.setVisibility(false)
aber
Wenn Sie die Sichtbarkeit der Optionen im ContextMenu ändern möchten, können Sie beim Drücken Ihrer Taste ein Flag aktivieren und dann im onCreateContextMenu Folgendes tun:
@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();
}
}
ich hoffe das hilft
onCreateContextMenu
Methode ändern kann . Ich möchte jedoch außerhalb dieser Methode auf das Kontextmenü zugreifen.
onCreateContextMenu
wird nur einmal aufgerufen, aber ich kann viel Zeit auf die Schaltfläche klicken, um den Menüpunkt zu aktivieren / deaktivieren.
setEnable()
ändert sich, was passiert, wenn Sie dieses Menü drücken, ändert aber nicht, wie es aussieht (was ist los, Android-Entwickler?). Es ist also klarer, entweder den Titel zu deaktivieren und zu ändern oder vorzugsweise nur dasMenuItem
Unsichtbare zu machen.