Ist es möglich, ein MenuItem in Android auszugrauen (nicht nur zu deaktivieren)?

Lesezeit: 11 Minuten

Benutzer-Avatar
Wayn Lue

Es gibt eine Frage zur gleichen Funktionalität auf Blackberry, und ein paar verschiedene Threads haben sich darauf bezogen Insekt (das, soweit ich das beurteilen kann, ohne Auflösung geschlossen wurde), aber ich habe keine speziell für Android gefunden.

Ich rufe an setEnabled(false) auf bestimmten MenuItems basierend auf einem bestimmten Zustand, aber sie sehen visuell gleich aus. Ich möchte, dass sie irgendwie versetzt werden, damit der Benutzer weiß, dass die Option derzeit nicht verfügbar ist. Gibt es eine Möglichkeit, dies zu tun?

Auf allen Android-Versionen können Sie dies am einfachsten verwenden, um ein Menüaktionssymbol als deaktiviert ANZUZEIGEN UND es auch als deaktiviert zu FUNKTIONIEREN:

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

  • Das ist genau das, wonach ich gesucht habe.

    – ElliotM

    1. April 2014 um 19:58 Uhr

  • Ja, das hat den Trick für mich getan, schön, das ursprüngliche Symbol behalten zu können.

    – Dale Zak

    25. November 2014 um 23:28 Uhr

  • Hinweis: Wenn dieses Symbol anderweitig verwendet wird, achten Sie darauf, es vor dem Setzen von alpha zu mutieren(), da sonst alle Stellen, die dieses Drawable verwenden, angepasst werden, was nicht unbedingt das ist, was Sie möchten.

    – dimsuz

    9. April 2015 um 19:28 Uhr

  • Gibt es eine andere Möglichkeit, den Alpha-Wert festzulegen? (innerhalb des Stils)

    – balaji

    16. September 2015 um 12:14 Uhr


  • Beachten Sie, dass dies nur funktioniert, wenn Ihr MenuItem ein Symbol ist. Funktioniert nicht für Nur-Text-MenuItems.

    – Iwan

    18. Juni 2018 um 23:50 Uhr

Benutzer-Avatar
Oleg Waskewitsch

Ich hatte das gleiche Problem. Es gibt zwei Möglichkeiten, dies zum Laufen zu bringen:

  1. Platzieren Sie Ihre Symbole in einer StateList, sodass beim Deaktivieren ein anderes Symbol verwendet wird
  2. Was ich jetzt benutze. Ändern Sie das Symbol selbst mit so etwas in onPrepareOptionsMenu():

    public boolean onPrepareOptionsMenu(Menu menu) {
        boolean menusEnabled = reachedEndOfSlidehow(); // enable or disable?
        MenuItem item = menu.findItem(R.id.menu_next_slide);
        Drawable resIcon = getResources().getDrawable(R.drawable.ic_next_slide);
    
        if (!menusEnabled)
            resIcon.mutate().setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN);
    
        item.setEnabled(menusEnabled); // any text will be automatically disabled
        item.setIcon(resIcon);
    }
    

Du kannst anrufen invalidateOptionsMenu() (oder aus ABS, supportInvalidateOptionsMenu()), um das Menü neu zu erstellen.

BEARBEITEN: Aktualisierte Lösung 2

Quelle: https://groups.google.com/forum/?fromgroups#!topic/actionbarsherlock/Z8Ic8djq-3o

  • Ändert dies jedoch tatsächlich die Farbe des Menüpunkttextes / -titels? Das heißt, ist es ausgegraut? Soweit ich weiß, wirkt sich dies nur auf das Symbol aus. Was ist, wenn Sie kein Symbol und nur Text haben?

    – Toni Chan

    7. November 2012 um 2:25 Uhr

  • Der Aufruf von item.setEnabled() lässt den Text bereits ausgegraut erscheinen. Das Problem ist, dass auf Aktionsleisten der Text ausgegraut ist, das Symbol jedoch nicht – dieser Code macht es ausgegraut.

    – Oleg Waskewitsch

    7. November 2012 um 6:57 Uhr

  • Die Antwort von Nobu Games auf den von Ihnen verlinkten Google Groups-Thread hat bei mir in Jelly Bean hervorragend funktioniert: menuItem.getIcon().setAlpha(enabled ? 255 : 64);

    – Poshaughnessy

    2. Januar 2013 um 16:55 Uhr


Benutzer-Avatar
Bryan

Ich habe einen neuen Weg gefunden, um dieses Problem mit einer XML-Datei mit einem zeichbaren Selektor zu lösen. Sie erstellen einfach einen Selektor mit dem Symbol, das Sie in Ihrem Menüpunkt verwenden möchten, dann können Sie entweder den Farbton, Alpha oder beides der Bitmap ändern:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_enabled="true">
        <bitmap android:src="https://stackoverflow.com/questions/9642990/@drawable/ic_menu_item"
            android:tint="@color/enabled_color"
            android:alpha="@integer/enabled_alpha"/>
    </item>

    <item android:state_enabled="false">
        <bitmap android:src="https://stackoverflow.com/questions/9642990/@drawable/ic_menu_item"
            android:tint="@color/disabled_color"
            android:alpha="@integer/disabled_alpha"/>
    </item>
</selector>

Als Anmerkung; Ich stelle die Tönung gerne auf ein "?android:attr/textColorPrimary" für aktivierten Zustand und "?android:attr/textColorHint" für behinderten Zustand. Auf diese Weise wird es je nach verwendetem Thema angepasst.


Dann können Sie einfach das Symbol in Ihrer Menü-XML-Datei auf die Auswahlressource setzen:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/menu_action"
        android:orderInCategory="0"
        android:title="@string/title_menu_action"
        android:icon="@drawable/ic_menu_item_selector"
        app:showAsAction="ifRoom"/>

</menu>

Dann, wenn Sie anrufen item.setEnabled(enabled) die Farbe und/oder Alpha des Symbols ändert sich zusammen mit dem Zustand!

  • Diese Lösung ist nur für Android 5.0+ (API 21+) Lollipop und höher geeignet, daher ist setColorFilter in früheren Versionen erforderlich.

    – Streuner

    19. August 2016 um 4:59 Uhr

  • Wie teuer ist das im Vergleich dazu, nur die Symbole in 2 verschiedenen Farben vorzubereiten und sie auszutauschen?

    – Ryuu

    24. April 2020 um 13:21 Uhr

  • @Ryuu User Vector Drawable und Farben ändern. anstelle von zwei PNG-Dateien

    – Manikandan Selvanathan

    4. September 2020 um 21:18 Uhr

Die Art und Weise, wie ich es gemacht habe, ist die Verwendung von “itemIconTint” in NavigationView, Sie können den Text auch ausgrauen, indem Sie “itemTextColor” verwenden.

Dies ist die Navigationsansicht:

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:itemBackground="@color/white"
    android:background="@color/white"
    app:itemTextColor="@color/menu_text_color"
    app:itemIconTint="@color/menu_text_color"
    app:menu="@menu/main_drawer" />

und “@color/menu_text_color” ist ein Selektor:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="@color/primaryColor" />
    <item android:state_enabled="false" android:color="@color/disabled_text_color" />
    <item android:color="@color/primaryText" />
</selector>

Wenn Sie schließlich einen Menüpunkt deaktivieren möchten,

MenuItem item = mNavigationView.getMenu().findItem(R.id.your_menu_item);
item.setEnabled(isEnable);

Fertig!

Ich hatte ein Problem, bei dem sich weder mein Text noch das Symbol sichtbar änderten. Die anderen Antworten haben bei mir entweder nicht funktioniert oder waren nicht sehr elegant. Hier ist eine Antwort, die für die neuesten funktioniert Materialempfehlungen.

Du sollte einfach anrufen können menu.findItem(R.id.menu_my_item).isEnabled = false in onPrepareOptionsMenu(menu: Menu).

(Wenn Sie brauchen onPrepareOptionsMenu um wieder zu laufen, kannst du einfach anrufen invalidateOptionsMenu() oder activity?.invalidateOptionsMenu() (aus einem Fragment) und die Anwendung stellt das neu zu erstellende Menü in die Warteschlange. Alternativ können Sie das Menüelement in einer Mitgliedsvariablen speichern, um es später zu ändern, aber achten Sie darauf, Ihre Referenz darauf zu zerstören onDestroyOptionsMenu um ein Speicherleck zu vermeiden.)

Die Tatsache, dass der Menüpunkt deaktiviert ist sollte ausreichen, um den Text oder das Symbol automatisch auszugrauen. Die Schwierigkeit besteht darin, Ihre Stile so einzurichten, dass dies funktioniert.

Kurze Antwort

Erstellen Sie zunächst eine Farbzustandsliste my_color_state_list.xml die Sie für Ihre Symbole und Ihren Text verwenden möchten (z. B. schwarz, wenn aktiviert, grau, wenn deaktiviert). (Ein Beispiel finden Sie in der vollständigen Antwort.)

Wenn Sie verwenden com.google.android.material.appbar.MaterialToolbar, können Sie ihm mitteilen, dass dieser Selektor für Symbole und Text verwendet werden soll, indem Sie ein benutzerdefiniertes Design-Overlay bereitstellen. Weisen Sie der Symbolleiste im XML-Code Ihrer Aktivität das Attribut zu android:theme="@style/Foo" und definiere diesen Stil irgendwo als:

    <style name="Foo">
        <item name="colorControlNormal">@color/my_color_state_list</item>
        <item name="actionMenuTextColor">@color/my_color_state_list</item>
    </style>

Jetzt, wenn der Menüpunkt aktiviert oder deaktiviert ist über menu.findItem(R.id.menu_my_item).isEnabled = false Der Text ändert automatisch die Farbe und alle Symbole, die diese Farbe verwenden ?attr/colorControlNormal ändert auch automatisch die Farbe.

Vollständige Antwort

Mein Startplatz

Meine Menüpunkte sind Teil einer Materialsymbolleiste. Diese Antwort kann für andere Arten von Symbolleisten/App-Leisten hilfreich sein, aber Ihre Laufleistung kann variieren. In meiner Tätigkeit habe ich so etwas:

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.MaterialComponents.Toolbar.Surface"/>

und das Thema, das ich verwende, sieht in etwa so aus:

    <style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <item name="colorPrimary">@color/blue</item>
        <item name="colorSecondary">@color/green</item>
        <item name="colorSurface">@color/lightGrey</item>
        <item name="colorOnSurface">@color/black</item>
        [...]
        <item name="windowActionModeOverlay">true</item>
    </style>

Es ist auch Konvention, dass das Symbol, das Sie in Schaltflächen und Menüelementen (und eigentlich überall) verwenden, ihre Standardfarbe haben sollte ?attr/colorControlNormal. So könnte ich zum Beispiel ein Vektorbild haben, das so aussieht:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal"
    android:tintMode="src_atop">
  <path android:pathData="..." android:fillColor="@android:color/white"/>
</vector>

Wenn Sie ein Symbol von herunterladen Materielle Symbole Sie werden sehen, dass sie alle colorControlNormal verwenden.

Was ich tun musste

Wenn Sie sich die Definition meiner Symbolleiste ansehen, werden Sie sehen, dass sie ein ThemeOverlay verwendet ThemeOverlay.MaterialComponents.Toolbar.Surface was definiert ist als:

<style name="ThemeOverlay.MaterialComponents.Toolbar.Surface" parent="">
    <item name="colorControlNormal">@color/material_on_surface_emphasis_medium</item>
    <item name="actionMenuTextColor">@color/material_on_surface_emphasis_medium</item>
</style>

Dies stellt die Textfarbe des Menüpunkts und die Symbolfarbe auf ein @color/material_on_surface_emphasis_medium die nicht darauf reagiert, aktiviert zu werden oder nicht. @color/material_on_surface_emphasis_medium sieht aus wie:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:alpha="@dimen/material_emphasis_medium" android:color="?attr/colorOnSurface"/>
</selector>

(Möglicherweise verwenden Sie ThemeOverlay.MaterialComponents.Toolbar.Primary stattdessen, das ein ähnliches Problem hat – es verwendet einfach colorOnPrimary.)

Wir müssen dies durch unsere eigene Farbzustandsliste ersetzen, die auf den aktivierten Zustand reagiert. Erstellen Sie also eine neue Datei res/color/menu_item_selector.xml das sieht in etwa so aus:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:alpha="@dimen/material_emphasis_medium" android:color="?attr/colorOnSurface"/>
    <item android:alpha="@dimen/material_emphasis_disabled" android:color="?attr/colorOnSurface"/>
</selector>

Wie Sie sehen, habe ich dieselben Konventionen verwendet wie die Materialbibliothek, indem ich ihre Konstanten zum Definieren der Alpha-Werte verwendet habe, und ich habe sie verwendet colorOnSurface als meine Farbe. Wenn Sie verwendet haben ThemeOverlay.MaterialComponents.Toolbar.Primary Du würdest wollen colorOnPrimary stattdessen. Natürlich können Sie hier jede Farbe oder Alpha verwenden, es liegt an Ihnen.

Und jetzt machen Sie ein neues ThemeOverlay in res/values/styles.xml um auf diesen Selektor zu zeigen, der von dem von Ihnen verwendeten ThemeOverlay erbt:

<!-- Toolbar - overrides the menu text color to use a selector that responds to whether it's enabled or not -->
    <style name="ThemeOverlay.MyTheme.Toolbar" parent="ThemeOverlay.MaterialComponents.Toolbar.Surface">
        <!-- Color used in the icons of menu actions (i.e. non-overflow menu items). This is just convention, this will affect anything that uses ?attr/colorControlNormal) -->
        <item name="colorControlNormal">@color/menu_item_color_selector</item>
        <!-- Color used in the text of menu actions (i.e. non-overflow menu items) -->
        <item name="actionMenuTextColor">@color/menu_item_color_selector</item>
    </style>

Und jetzt können wir das endlich anwenden ThemeOverlay zur Symbolleiste:

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.MyTheme.Toolbar"/>

Benutzer-Avatar
Dhanuka

setEnabled(false) funktioniert gut auf API Level < 14 aber weiter 14 das Element ist immer noch anklickbar.

Benutzer-Avatar
Mariusz Wiazowski

Ich hatte Schwierigkeiten damit auf einem modernen Android mit MaterialComponents-Design. Mein Problem war, dass ich eingestellt hatte <item name="actionMenuTextColor">@color/blue</item> in styles.xml und dies überschreibt die Textfarbe, unabhängig davon, ob das Element aktiviert oder deaktiviert ist. Die Lösung besteht darin, a einzustellen Farbzustandsliste und nicht direkt eine Farbe.

Mein Styles-Attribut sieht jetzt so aus:

<item name="actionMenuTextColor">@color/menu_color_selector</item>

  • Ich hatte genau das gleiche Problem. Vielen Dank!

    – Mariusz Wiazowski

    26. März 2020 um 16:17 Uhr

  • Ich hatte das gleiche Problem, aber actionMenuTextColor hat für mich keinen Unterschied gemacht (ich habe es auf rosa gestellt und konnte nirgendwo rosa sehen). Wenn jemand, der sich das ansieht, immer noch Probleme mit Materialkomponenten hat, lesen Sie meine Antwort stackoverflow.com/a/66248473/5437033.

    – Chrispher

    17. Februar 2021 um 19:11 Uhr

1128880cookie-checkIst es möglich, ein MenuItem in Android auszugrauen (nicht nur zu deaktivieren)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy