Ich habe viel über invalidateOptionsMenu()
gesucht und weiß, was es bewirkt. Ich kann mir jedoch kein reales Beispiel vorstellen, wo diese Methode nützlich sein könnte.
Ich meine zum Beispiel, wir wollen unserer MenuItem
eine neue ActionBar
hinzufügen, wir können einfach das Menü von onCreateOptionsMenu(Menu menu)
bekommen und es in jeder Aktion einer Schaltfläche verwenden.
Nun zu meiner eigentlichen Frage, folgt der only - Art, invalidateOptionsMenu()
zu verwenden?
bool _OtherMenu;
protected override void OnCreate (Bundle bundle)
{
_OtherMenu = false;
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate
{
if(_OtherMenu)
_OtherMenu = false;
else
_OtherMenu = true;
InvalidateOptionsMenu ();
};
}
public override bool OnCreateOptionsMenu (IMenu menu)
{
var inflater = this.SupportMenuInflater;
if(_OtherMenu)
inflater.Inflate (Resource.Menu.another_menu, menu);
else
inflater.Inflate (Resource.Menu.main_activity_menu, menu);
return base.OnCreateOptionsMenu (menu);
}
Klicken Sie auf die Schaltfläche und ein anderes Menü wird angezeigt. Klicken Sie erneut auf die Schaltfläche und das vorherige Menü wird angezeigt.
P.S. Entschuldigung für die C # -Syntax.
invalidateOptionsMenu()
wird verwendet, um Android mitzuteilen, dass sich der Inhalt des Menüs geändert hat und das Menü neu gezeichnet werden sollte. Beispielsweise klicken Sie auf eine Schaltfläche, die zur Laufzeit ein weiteres Menüelement hinzufügt oder die Menüelementegruppe verbirgt. In diesem Fall sollten Sie invalidateOptionsMenu()
aufrufen, damit das System es auf der Benutzeroberfläche neu zeichnen kann. Diese Methode ist ein Signal für das Betriebssystem, um onPrepareOptionsMenu()
aufzurufen, bei dem Sie die erforderlichen Menümanipulationen implementieren . Außerdem wird OnCreateOptionsMenu()
während der Erstellung der Aktivität (Fragment) nur einmal aufgerufen. Daher können Laufzeitmenüänderungen nicht von dieser Methode verarbeitet werden.
Alle finden Sie in Dokumentation :
Nachdem das System onCreateOptionsMenu () aufgerufen hat, behält es eine Instanz des Menüs, das Sie ausfüllen und onCreateOptionsMenu () nicht erneut aufrufen es sei denn, das Menü ist aus irgendeinem Grund ungültig. Sie sollten jedoch Verwenden Sie nur onCreateOptionsMenu (), um den ursprünglichen Menüzustand und .__ zu erstellen. Änderungen nicht während des Aktivitätslebenszyklus vornehmen.
Wenn Sie das Optionsmenü basierend auf aufgetretenen Ereignissen ändern möchten Während des Aktivitätslebenszyklus können Sie dies im .__ tun. onPrepareOptionsMenu () - Methode. Diese Methode übergibt Ihnen das Menu-Objekt so wie Sie es derzeit haben, können Sie es ändern, z. B. hinzufügen, entfernen oder Elemente deaktivieren (Fragmente stellen auch einen onPrepareOptionsMenu () Rückruf bereit.)
Unter Android 2.3.x und niedriger ruft das System onPrepareOptionsMenu () .__ auf. Jedes Mal, wenn der Benutzer das Optionsmenü öffnet (drückt die Menütaste).
Unter Android 3.0 und höher gilt das Optionsmenü als immer Wird geöffnet, wenn Menüelemente in der Aktionsleiste angezeigt werden. Wenn ein Ereignis Wenn Sie eine Menüaktualisierung durchführen möchten, müssen Sie .__ aufrufen. invalidateOptionsMenu (), um den Systemaufruf anzufordern onPrepareOptionsMenu ().
verwenden Sie diese Option, um das neue Menü während des App-Lebenszyklus neu zu laden:
ActivityCompat.invalidateOptionsMenu(getActivity());
Sie müssen die Methode onPrepareOptionsMenu()
überschreiben, den Aktualisierungscode des Aktionsmenüs in derselben Methode schreiben. Wenn Sie fragment verwenden, fügen Sie setHasOptionsMenu(true);
in onCreateView()
hinzu.
Ich hoffe es hilft dir
Eine Anwendung, die ich gefunden habe, ist das Erzwingen einer Reihenfolge von Operationen zwischen onResume
und onCreateOptionsMenu/onPrepareOptionsMenu
. Die natürliche Reihenfolge (zumindest ab Plattform 22) scheint umzukehren, insbesondere wenn Sie Ihr Gerät neu ausrichten.
Rufen Sie invalidateOptionsMenu
() in onResume
() auf und Sie garantieren, dass onPrepareOptionsMenu
nach onResume aufgerufen wird (es kann auch zuvor aufgerufen werden). So können Sie beispielsweise ein Menüelement aktivieren, das auf Daten basiert, die in onResume
abgerufen werden.
Es ist alt, aber ich hoffe, das hilft jemandem in der Zukunft.
Eine Verwendung, die ich in einem realen Szenario gefunden habe:
Angenommen, Sie haben eine Liste von Elementen, die in der Datenbank gespeichert sind, und Sie haben zwei Aktivitäten:
Sie haben sich für ein paar Optionen entschieden, um von DisplayActivity zu EditActivity zu wechseln:
Um sich nicht durch Duplizieren von Code zu wiederholen, haben Sie sich entschieden, EditActivity für beide Zwecke zu verwenden.
Daher möchten Sie das Optionsmenü an jeden Zweck anpassen. In diesem Fall würden Sie mit onCreateOptionsMenu()
ein Standardoptionsmenü erstellen und es unverändert lassen, wenn es Zeit ist, ein vorhandenes Element zu bearbeiten. und invalidateOptionsMenu()
es, wenn es Zeit ist, neue Elemente zu erstellen; und in diesem Fall wird onPrepareOptionsMenu()
automatisch ausgelöst, um Ihr Menü anzupassen.
Beispielsweise kann das Menü Optionen eine Löschoption zum Bearbeiten eines vorhandenen Elements enthalten, die beim Hinzufügen eines neuen Elements ausgeblendet werden sollte.
/** * Set a hint for whether this fragment's menu should be visible. This * is useful if you know that a fragment has been placed in your view * hierarchy so that the user can not currently seen it, so any menu items * it has should also not be shown. * * @param menuVisible The default is true, meaning the fragment's menu will * be shown as usual. If false, the user will not see the menu. */ public void setMenuVisibility(boolean menuVisible) { if (mMenuVisible != menuVisible) { mMenuVisible = menuVisible; if (mHasMenu && isAdded() && !isHidden()) { mHost.onSupportInvalidateOptionsMenu(); } } }
XML-Menübeispiel:
<?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_edit"
Android:icon="@drawable/ic_edit"
Android:title="Edit Task"
app:showAsAction="always" />
<item
Android:id="@+id/action_delete"
Android:icon="@drawable/ic_delete"
Android:title="Delete Task"
app:showAsAction="always" />
<item
Android:id="@+id/action_check"
Android:icon="@drawable/ic_check"
Android:title="Check Task"
app:showAsAction="always" />
<item
Android:id="@+id/action_uncheck"
Android:icon="@drawable/ic_undo"
Android:title="Uncheck Task"
app:showAsAction="always" />
</menu>
Code innerhalb eines Beispielfragments:
private boolean isMenuItemChecked;
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setMenuVisibility(false);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.my_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
try {
menu.findItem(R.id.action_check).setVisible(!isMenuItemChecked);
menu.findItem(R.id.action_uncheck).setVisible(isMenuItemChecked);
}
catch(Exception e) {
Log.e(TAG, "onPrepareOptionsMenu error");
}
}
public void loadUi(boolean isMenuItemChecked) {
this.isMenuItemChecked = isMenuItemChecked;
setMenuVisibility(true);
}
Der beste Weg, der für mich funktioniert hat, wird im Folgenden gezeigt
Setzen Sie den Anfangsstatus des Menüs in onCreateOptionsMenu (...)
Verwenden Sie die invalidateOptionsMenu (), um onCreateOptionsMenu (...) und onPrepareOptionsMenu (...) zu erzwingen.
Rufen Sie in onPrepareOptionsMenu (...) menu.clear () auf, um alle Elemente aus dem Menü zu entfernen.
In onPrepareOptionsMenu (...) platzieren Sie Ihre dynamischen Menüänderungen nach dem Löschen
Hoffe das hilft...
Edit: Hier ist eine bessere Antwort auf die Frage.
Eine gute Verwendung für invalidateOptionsMenu()
ist, wenn wir eine ListView
und Delete All MenuItem
haben. Wenn die ListView
leer ist, sollten wir invalidateOptionsMenu()
verwenden, um die Delete All MenuItem
zu entfernen.
Hier ist eine Frage zu dieser Antwort: Frage .
Vom Fragmentaufruf getActivity().invalidateOptionsMenu();
.