15

Ich habe viel auf invalidateOptionsMenu() gesucht und ich weiß, was es tut. Aber ich kann mir kein wirkliches Beispiel vorstellen, wo diese Methode nützlich sein könnte.Android - Korrekte Verwendung von invalidateOptionsMenu()

ich meine, zum Beispiel, lassen Sie uns sagen, dass wir ein neues MenuItem unserer ActionBar hinzufügen wollen, können wir einfach das Menü von onCreateOptionsMenu(Menu menu) bekommen und es in eine beliebige Taste-Aktion verwenden.

Nun zu meiner echten Frage, folgt die nur Art der Verwendung invalidateOptionsMenu()?

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.

+0

Was ist Ihre MinSdkVersion? – Xcihnegn

+0

Es funktioniert auf 11+. Meins ist 15. –

+0

So sollte es OnCreateOptionsMenu() aufrufen, könnten Sie versuchen, Debug zu laufen, um durch die Codes – Xcihnegn

Antwort

2

Sie müssen die Methode onPrepareOptionsMenu() überschreiben, schreiben Sie Ihren Aktualisierungscode des Aktionsmenüs in derselben Methode und wenn Sie ein Fragment verwenden, fügen Sie setHasOptionsMenu(true); in onCreateView() hinzu.

Hoffe, dass es Sie ist

+0

zu ändern, aber onPrepareOptionsMenu() ist nur eine feste Methode. Mit festen ich meine, es ist nicht der Fall, dass einmal onPrepareOptionsMenu() etwas tut und andere Zeit es etwas anderes tut. –

+0

Warum nicht? Es gibt so etwas wie Bedingungen (wenn-sonst), weißt du.Sie können es tun, was Sie wollen in jeder Situation, die Sie sich vorstellen –

+0

das ist genau meine Frage. Ist das der einzige Ansatz, um diese Methode zu verwenden ??? –

44

invalidateOptionsMenu() verwendet hilft Android zu sagen, dass der Inhalt des Menüs haben sich geändert, und Menü sollte neu gezeichnet werden. Beispielsweise klicken Sie auf eine Schaltfläche, die zur Laufzeit einen weiteren Menüeintrag hinzufügt, oder blendet die Menüelementgruppe aus. 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 onPrepareOptionsMenu(), in dem Sie die erforderlichen Menümanipulationen implementieren. Außerdem wird OnCreateOptionsMenu() nur einmal während der Erstellung der Aktivität (Fragment) aufgerufen, daher können Änderungen im Laufzeitmenü mit dieser Methode nicht behandelt werden.

Alle können in documentation finden:

Nachdem das System ruft onCreateOptionsMenu(), behält es eine Instanz des Menüs Sie bevölkern und onCreateOptionsMenu nicht nennen() erneut es sei denn, das Menü für ungültig erklärt irgendein Grund. Sie sollten jedoch onCreateOptionsMenu() nur verwenden, um den anfänglichen Menüstatus zu erstellen, und , um während des Aktivitätslebenszyklus keine Änderungen vorzunehmen.

Wenn Sie das Optionsmenü basierend auf Ereignissen ändern möchten, die während des Aktivitätslebenszyklus auftreten, können Sie dies in der onPrepareOptionsMenu() -Methode tun. Diese Methode übergibt Ihnen das Menüobjekt , wie es derzeit existiert, so dass Sie es ändern können, wie Hinzufügen, Entfernen oder Elemente deaktivieren. (Fragmente auch eine onPrepareOptionsMenu() Rückruf bieten.)

Auf Android 2.3.x und niedriger, ruft das System onPrepareOptionsMenu() jedes Mal, wenn der Benutzer das Optionsmenü öffnet (drückt die Menütaste).

Unter Android 3.0 und höher wird das Optionsmenü immer als geöffnet angezeigt, wenn Menüelemente in der Aktionsleiste angezeigt werden. Wenn ein Ereignis auftritt und Sie eine Menüaktualisierung durchführen möchten, müssen Sie invalidateOptionsMenu() aufrufen, um den Systemaufruf onPrepareOptionsMenu() anzufordern.

+0

aber ich muss nicht invalidateOptionsMenu() aufrufen. Ich mache einfach menu.add() und es wird angezeigt –

+0

Es ist für dynamische Menüs erforderlich. Wie können Sie 'menu.add () 'von außen' onCreateOptionsMenu() '? Wie können Sie zB Menüpunkte ändern, wenn der Benutzer eine Listenansicht herunterscrollt? Indem er das Menü beim Scrollen ungültig macht, erzwingt er die Aktivität und prüft auf eine bestimmte Bedingung in' onCreateOptionsMenu() '. Das würde nicht funktionieren, wenn Sie nach der Bedingung in' onCreateOptionsMenu() 'suchen, ohne zu invalidieren, weil die Aktivität das Menü immer noch für OK hält. – natario

+0

Ich weiß nicht, wie man hier Code schreibt, aber wir sehen: OnCreateOptionsMenu (IM Menü) { _Menu = Menü; } Und Sie haben den Verweis auf Menü. Jetzt tun, was auch immer Sie tun möchten –

0

Edit: Hier ist eine bessere Antwort auf die Frage.

Eine gute Verwendung für invalidateOptionsMenu() ist, wenn wir eine ListView haben und löschen Sie alle MenuItem so, wenn die ListView leer ist, sollten wir invalidateOptionsMenu() verwenden, um das All MenuItem zu entfernen löschen.

Hier ist eine Frage im Zusammenhang mit dieser Antwort: Question.

+0

Wenn Sie eine neue Frage haben, bitte fragen Sie, indem Sie auf die Schaltfläche [Frage stellen] (http://stackoverflow.com/questions/ask) klicken . Fügen Sie einen Link zu dieser Frage hinzu, wenn es hilft, Kontext bereitzustellen. - [Aus Review] (/ review/low-quality-posts/14147349) – sushildlh

+0

Tatsächlich bietet dieser Link Kontext zur Antwort @sushildlh –

0
/** 
* 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 einer Probe Fragment:

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

Verwendung dieses neue Menü während der App-Lebenszyklus laden:

ActivityCompat.invalidateOptionsMenu(getActivity()); 
+0

in welchem ​​Lebenszyklus von Fragment sollten wir das nennen? –

+2

jeder Punkt im Leben, klicken Sie auf, klicken Sie auf usw. – itzhar

0

Der beste Weg, die für mich gearbeitet wird unter

    demonstriert
  1. Setzen Sie den Anfangszustand des Menüs in onCreateOptionsMenu (...)

  2. Verwenden Sie die invalidateOptionsMenu() zu zwingen onCreateOptionsMenu (.. .) und onPrepareOptionsMenu (...)

  3. In onPrepareOptionsMenu (...) rufen Sie menu.clear() auf, um alle Elemente aus dem Menü zu entfernen.

  4. Noch in onPrepareOptionsMenu (...) Ihr dynamisches Menü ändert sich nach dem klaren

Hoffnung setzen, das hilft ...

0

Eine Verwendung ich gefunden habe, ist eine Reihenfolge der Operationen zwingen zwischen onResume und onCreateOptionsMenu/onPrepareOptionsMenu. Die natürliche Reihenfolge (zumindest ab Plattform 22) scheint sich umzudrehen, besonders wenn Sie Ihr Gerät neu ausrichten.

Rufen Sie invalidateOptionsMenu() in onResume() und Sie werden garantieren, dass onPrepareOptionsMenu nach onResume aufgerufen werden (es kann zusätzlich zuvor aufgerufen werden). Dies ermöglicht beispielsweise die Aktivierung eines Menüelements basierend auf Daten, die in onResume abgerufen wurden.