Is it possible to grey out (not just disable) a MenuItem in Android?

…衆ロ難τιáo~ 提交于 2019-11-28 16:40:04

问题


There's a question for the same functionality on Blackberry, and a few different threads referred to this bug (which has since been closed without resolution as far as I can tell), but I haven't found one specifically for Android.

I'm calling setEnabled(false) on certain MenuItems based on some state, but they visually look the same. I'd like them to be offset in some way, so that the user knows that the option currently isn't available -- is there any way to do that?


回答1:


I had the same issue. There are two ways of getting this to work:

  1. Put your icons in a StateList so that a different icon will be used on disable
  2. What I use now. Change the icon yourself with something like this 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);
    }
    

You can call invalidateOptionsMenu() (or from ABS, supportInvalidateOptionsMenu()) to rebuild the menu.

EDIT: Updated solution 2

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




回答2:


On all android versions, easiest way to use this to SHOW a menu action icon as disabled AND make it FUNCTION as disabled as well:

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



回答3:


I found a new way to solve this issue using a drawable selector xml file. You just create a selector with the icon you want to use in your menu item, then you can either change the tint, alpha or both of the bitmap:

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

As a side note; I like to set the tint to "?android:attr/textColorPrimary" for enabled state and "?android:attr/textColorHint" for disabled state. This way it will adjust depending on the theme used.


Then you can just set the icon in your menu xml file to the selector resource:

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

Then when you call item.setEnabled(enabled) the color and/or alpha of the icon will change along with the state!




回答4:


The way I did it is by using "itemIconTint" in NavigationView, you can also grey out the text by using "itemTextColor"

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

and the "@color/menu_text_color" is a selector:

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

Finally, if you want to disable a menuitem,

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

Done!




回答5:


setEnabled(false) works fine on API Level < 14 but on 14 the item still clickable.




回答6:


Have a look at this link

setEnabled can also be used for MenuItems.




回答7:


Here's a simple way to do it (using 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)
}



回答8:


I was having difficulty with this on modern android with MaterialComponents theme. My problem was I had set <item name="actionMenuTextColor">@color/blue</item> in styles.xml and this overrides the text color whether the item is enabled or disabled. The solution is to set a Color state list and not a color directly.

My styles attribute now looks like:

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



来源:https://stackoverflow.com/questions/9642990/is-it-possible-to-grey-out-not-just-disable-a-menuitem-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!