web-dev-qa-db-fra.com

Est-il possible de griser (pas seulement désactiver) un MenuItem dans Android?

Il y a une question pour la même fonctionnalité sur Blackberry , et quelques fils de discussion différents se référant à ce bug (qui a depuis été fermé sans résolution, pour autant que je sache), spécifiquement pour Android.

J'appelle setEnabled(false) sur certains éléments de menu en fonction de certains états, mais ils se ressemblent visuellement. J'aimerais qu'ils soient compensés d'une certaine manière, afin que l'utilisateur sache que l'option n'est pas disponible pour le moment - y a-t-il un moyen de le faire?

36
Waynn Lue

J'ai eu le même problème. Il y a deux façons d'obtenir que cela fonctionne:

  1. Placez vos icônes dans une liste d'état afin qu'une autre icône soit utilisée lors de la désactivation.
  2. Ce que j'utilise maintenant. Changez l’icône vous-même avec quelque chose comme ceci dans 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);
    }
    

Vous pouvez appeler invalidateOptionsMenu() (ou depuis ABS, supportInvalidateOptionsMenu()) pour reconstruire le menu.

EDIT: Solution mise à jour 2

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

54
Oleg Vaskevich

Sur toutes les versions d'Android, la meilleure façon de l'utiliser est d'afficher une icône d'action de menu désactivée ET de la rendre fonctionnelle également:

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

J'ai trouvé une nouvelle façon de résoudre ce problème en utilisant un fichier XML de sélecteur pouvant être dessiné. Il vous suffit de créer un sélecteur avec l'icône que vous souhaitez utiliser dans votre élément de menu. Vous pouvez ensuite modifier la teinte, l'alpha ou les deux à la fois:

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

    <item Android:state_enabled="true">
        <bitmap Android:src="@drawable/ic_menu_item"
            Android:tint="@color/enabled_color"
            Android:alpha="@integer/enabled_alpha"/>
    </item>

    <item Android:state_enabled="false">
        <bitmap Android:src="@drawable/ic_menu_item"
            Android:tint="@color/disabled_color"
            Android:alpha="@integer/disabled_alpha"/>
    </item>
</selector>

Comme note de côté; J'aime définir la teinte sur "?android:attr/textColorPrimary" pour l'état activé et "?android:attr/textColorHint" pour l'état désactivé. De cette façon, il sera ajusté en fonction du thème utilisé.


Ensuite, vous pouvez simplement définir l’icône dans votre fichier XML de menu sur la ressource de sélecteur:

<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>

Ensuite, lorsque vous appelez item.setEnabled(enabled), la couleur et/ou l'alpha de l'icône changera en même temps que l'état!

7
Bryan

setEnabled(false) fonctionne bien sur API Level < 14 mais sur 14, l'élément est toujours cliquable.

2
Hoochwo

La manière dont je l'ai fait est d'utiliser "itemIconTint" dans NavigationView, vous pouvez également griser le texte en utilisant "itemTextColor"

C'est Navigationview:

<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" />

et "@ color/menu_text_color" est un sélecteur:

<?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>

Enfin, si vous voulez désactiver un menuitem, 

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

Terminé!

1
SoYoung

Voici un moyen simple de le faire (en utilisant Kotlin):

fun changeMenuItemColour(enabled: Boolean) {
    var menuItem = SpannableString(mCustomToolbar?.menu?.findItem(R.id.some_menu_item)?.title)
    var style = activity?.resources?.getColor(R.color.darkGraphite)!!
    if (enabled) style = activity?.resources?.getColor(R.color.black)!!
    menuItem.setSpan(ForegroundColorSpan(style), 0, menuItem.length, 0)
}
1
Andrew Odendaal

Jetez un coup d'oeil à ceci link

setEnabled peut également être utilisé pour MenuItems.

1
Pavandroid