ab11
ab11

Reputation: 20100

Android: how to detect click on disabled menu item?

I have some items in an ActionBar sub menu which I would like to conditionally disable, because they are not applicable for some contexts. I would like them to appear disabled (greyed out) to discourage users from clicking them; but if clicked, I would like to show a toast informing the user of why it is disabled ("can't do A because there is no B", etc). However, if I call MenuItem.setEnabled(false), it seems all the menu item click events do not occur. So, how do I detect click on the disabled menu item?

public class Temp extends Activity implements OnMenuItemClickListener
{
    boolean mConditional = true;

    protected void onCreate(Bundle state)
    {
        super.onCreate(state);
    }

    public boolean onMenuOpened(int featureId, Menu menu)
    {
        MenuItem item = (MenuItem) menu.findItem(R.id.item2);
        if(item != null && mConditional)
        {
            item.setEnabled(false);
            item.setOnMenuItemClickListener(this);
        }

        return super.onMenuOpened(featureId, menu);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) 
    {
        //does not fire if item is disabled
        Log.e("", item.getTitle().toString());
        return true;
    }



    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        //does not fire if item is disabled
        Log.e("", item.getTitle().toString());
        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item)
    {
        //does not fire if item is disabled
        Log.e("", item.getTitle().toString());
        return super.onMenuItemSelected(featureId, item);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return true;
    }
}

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu"
        android:icon="@drawable/ic_launcher"
        android:showAsAction="always"
        android:title="menu">
        <menu>
            <item
                android:id="@+id/item1"
                android:showAsAction="always"
                android:title="item 1"/>
            <item
                android:id="@+id/item2"
                android:showAsAction="always"
                android:title="item 2"/>
            <item
                android:id="@+id/item3"
                android:showAsAction="always"
                android:title="item 3"/>
        </menu>
    </item>
</menu>

Upvotes: 1

Views: 2347

Answers (1)

Aleks G
Aleks G

Reputation: 57346

You cannot use setEnabled for this. You need to keep menu items enabled all the time and simulate the "disabled" state by changing the drawable (or modifying it using porterduff filter - have a look at this question on how to dim images in android). Separately, you need to keep a flag indicating the state of the item - tag of the menu item is a good option. Ideally, you'd have something like this:

private void setMenuItemEnable(MenuItem item, boolean enabled) {
    int curstate = ((Integer)item.getTag()).intValue();

    if(curState == 1 && enabled || curstate == 0 && !enabled) {
        return;
    }

    if(enabled) {
        ... //update image to remove dimming
        item.setTag(1);
    }
    else {
        ... //update image by dimming it
        item.setTag(0);
    }
}

Finally, in your onOptionsItemSelected() method, check the tag of the chosen menu item and either perform the action if the tag is 1 or display the toast if the tag is 0. Visually it will be just what you want, and functionally it'll do what you're after.

Upvotes: 3

Related Questions